C language syntax

Hi guys,
I have some thing down here, It’s from the Wifi library for intel Edison (arduino compatible).

/*
Arduino WiFi Script Server

Created October 20, 2013
Mikael Kindborg, Evothings AB

TCP socket server that accept commands for basic scripting
of the Arduino board.

This example is written for a network using WPA encryption.
For WEP or WPA, change the Wifi.begin() call accordingly.

The API consists of the requests listed below.

Requests and responses end with a new line.

The input parameter n is a pin number ranging from 2 to 9.

The response is always a 4-character string with a
hex encoded number ranging from 0 to FFFF.

Possible response string values:

H (result from digital read)
L (result from digital read)
0 to 1023 - Analog value (result from analog read)

Set pin mode to OUTPUT for pin n: On
Response: None
Example: O5
Note: O is upper case letter o, not digit zero (0).

Set pin mode to INPUT for pin n: In
Response: None
Example: I5

Write LOW to pin n: Ln
Response: None
Example: L5

Write HIGH to pin n: Hn
Response: None
Example: H5

READ pin n: Rn
Response: "H" (HIGH) or "L" (LOW)
Example: R5 -> H

ANALOG read pin n: An
Response: int value as string (range "0" to "1023")
Example: A5 -> 42
*/

// Include files.
#include <SPI.h>
#include <WiFi.h>

// Remove this line once you've entered WiFi SSID and password below.
#error "WiFi SSID and password required!"

// Your network SSID (network name).
// TODO: Enter the name of your wifi network here.
char ssid[] = "wifi name";

// Your network password.
// TODO: Enter the password of your wifi network here.
char pass[] = "wifi password";

// Your network key Index number (needed only for WEP).
int keyIndex = 0;

// Server status flag.
int status = WL_IDLE_STATUS;

// Create WiFi server listening on the given port.
WiFiServer server(3300);

void setup()
{
	// Start serial communication with the given baud rate.
	// NOTE: Remember to set the baud rate in the Serial
	// monitor to the same value.
	Serial.begin(9600);

	// Wait for serial port to connect. Needed for Leonardo only
	while (!Serial) { ; }

	// Check for the presence of the WiFi shield.
	if (WiFi.status() == WL_NO_SHIELD)
	{
		// If no shield, print message and exit setup.
		Serial.println("WiFi shield not present");
		status = WL_NO_SHIELD;
		return;
	}

	String version = WiFi.firmwareVersion();
	if (version != "1.1.0")
	{
		Serial.println("Please upgrade the firmware");
	}

	// Connect to Wifi network.
	while (status != WL_CONNECTED)
	{
		Serial.print("Connecting to Network named: ");
		Serial.println(ssid);

		// Connect to WPA/WPA2 network. Update this line if
		// using open or WEP network.
		status = WiFi.begin(ssid, pass);

		// Wait for connection.
		delay(1000);
	}

	// Start the server.
	server.begin();

	// Print WiFi status.
	printWifiStatus();
}

void loop()
{
	// Check that we are connected.
	if (status != WL_CONNECTED)
	{
		return;
	}

	// Listen for incoming client requests.
	WiFiClient client = server.available();
	if (!client)
	{
		return;
	}

	Serial.println("Client connected");

	String request = readRequest(&client);
	executeRequest(&client, &request);

	// Close the connection.
	//client.stop();

	Serial.println("Client disonnected");
}

// Read the request line. The string from the JavaScript client ends with a newline.
String readRequest(WiFiClient* client)
{
	String request = "";

	// Loop while the client is connected.
	while (client->connected())
	{
		// Read available bytes.
		while (client->available())
		{
			// Read a byte.
			char c = client->read();

			// Print the value (for debugging).
			Serial.write(c);

			// Exit loop if end of line.
			if ('\n' == c)
			{
				return request;
			}

			// Add byte to request line.
			request += c;
		}
	}
	return request;
}

void executeRequest(WiFiClient* client, String* request)
{
	char command = readCommand(request);
	int n = readParam(request);
	if ('O' == command)
	{
		pinMode(n, OUTPUT);
	}
	else if ('I' == command)
	{
		pinMode(n, INPUT);
	}
	else if ('L' == command)
	{
		digitalWrite(n, LOW);
	}
	else if ('H' == command)
	{
		digitalWrite(n, HIGH);
	}
	else if ('R' == command)
	{
		sendResponse(client, String(digitalRead(n)));
	}
	else if ('A' == command)
	{
		sendResponse(client, String(analogRead(n)));
	}
}

// Read the command from the request string.
char readCommand(String* request)
{
	String commandString = request->substring(0, 1);
	return commandString.charAt(0);
}

// Read the parameter from the request string.
int readParam(String* request)
{
	// This handles a hex digit 0 to F (0 to 15).
	char buffer[2];
	buffer[0] = request->charAt(1);
	buffer[1] = 0;
	return (int) strtol(buffer, NULL, 16);
}

void sendResponse(WiFiClient* client, String response)
{
	// Send response to client.
	client->println(response);

	// Debug print.
	Serial.println("sendResponse:");
	Serial.println(response);
}

void printWifiStatus()
{
	Serial.println("WiFi status");

	// Print network name.
	Serial.print("  SSID: ");
	Serial.println(WiFi.SSID());

	// Print WiFi shield IP address.
	IPAddress ip = WiFi.localIP();
	Serial.print("  IP Address: ");
	Serial.println(ip);

	// Print the signal strength.
	long rssi = WiFi.RSSI();
	Serial.print("  Signal strength (RSSI):");
	Serial.print(rssi);
	Serial.println(" dBm");
}

I have some questions:

  1. In some function like sendResponse(), readParam(), … I see that we have “WifiClient* client” and something like that, what does the “" mean? Why we use that? And may I remove the "”?
  2. There is some lines like: “client->println(response);” (in sendResponse() function). What does the “->” do?

Please help me with this.

Best Regards

what does the "*" mean?

means it's a pointer to such an objet.

Why we use that?

to let the function work on the real object, not a copy.

And may I remove the "*"?

do you think they added this just so that it looks cool? --> read this

then you can also explore in C++ the notion of passing by value or reference.

J-M-L:
do you think they added this just so that it looks cool? --> read this

Nice answers :slight_smile:

  • says use the named variable as an address and get what is stored there and use it, so no it is not removable.

e->name is equivalent to (*e).name it is a way to get a member of a struct (or union) given a pointer.

:slight_smile:

really need to understand the concept of pointers and addresses it's used a lot.

Any variable has two components to it after it is defined: 1) an lvalue, which is the memory address where the variable is located in memory, and 2) an rvalue, which is the content, or value, of the variable. For example, the statement:

void setup() 
{
   int val;
}

might be compiled so that the variable is located at memory address 650. The content of val is unknow because we have assigned anything to it.

Now, if you add the statement:

void setup() 
{
   int val;

   val = 10;

}

the image changes to:

For most variables, the assignment is rvalue-to-rvalue. That is, you move the content of one varible’s rvalue into the rvalue of another variable. Now define a pointer:

void setup() 
{
   int val;
   int *ptr;

   val = 10;
   ptr = &val;
}

Pointers are designed to hold one of two values 1) NULL, which means the pointer contains nothing useful, or 2) the memory address (i.e., the lvalue) of another variable. If the compiler puts ptr at memory address 700, then the statments above result in:

Now we can use the process called indirection to use ptr to change the value of val:

void setup() 
{
   int val;
   int *ptr;

   val = 10;
   ptr = &val;
   *ptr = 20;
}

You can verbalize that last statement as: “Go to ptr (at address 700) and fetch its rvalue (650). Now go to that memory address (650) and place the value of 20 at that memory address.” Because val lives at memory address 650, ptr ends up changing the rvalue of val indirectly through val’s lvalue.

Now the task for you is to figure out why this is such a power tool. Hint: suppose a function determines the min and max of a data set and you want to know both of them. However, a function can only return one value. What would you do?

I hate lvalue error messages :-X

http://cdecl.org

Thanks all,
Hi @econjack, I can now understand some more about pointer, but, about your task, I still don't really understand why we have to use this. I read some topics and they said that some languages such as Java or C/C++ now have "Automatic Memory Management" so the pointer is not nessesary. But I still really want to understand the pointer concept and why this stuff is so powerfull. Thanks all!

Try this example and it will show you one good example of why we have it.

int a = 3;
int b = 3;

int addOne(int x){
    x++;
    return x;
}

int addOneP(int *x){
    (*x)++;
    return *x;
}

void setup(){
     Serial.begin(9600);
     Serial.print("Starting out: a = ");
     Serial.print(a);
     Serial.print(" and b = ");
     Serial.println(b);

     Serial.print("Calling with int gets: ");
     Serial.println(addOne(a));
     Serial.print("Calling with int* gets: ");
     Serial.println(addOneP(&b);
     
     Serial.print("Afterwards: a = ");
     Serial.print(a);
     Serial.print(" and b = ");
     Serial.println(b); 
}

void loop(){}

ductruong253:
Thanks all,
Hi @econjack, I can now understand some more about pointer, but, about your task, I still don't really understand why we have to use this. I read some topics and they said that some languages such as Java or C/C++ now have "Automatic Memory Management" so the pointer is not nessesary. But I still really want to understand the pointer concept and why this stuff is so powerfull. Thanks all!

C++ does not have automatic garbage collection. Garbage collection is a big job, requiring big, lumpy code that won't generally fit on a microprocessor. It's also inclined to be slow, which once again is a problem on something running and 16MHz.

Garbage collection does not make pointers unnecessary. It's just that things like java and scripting languages use dynamically allocated memory and pointers for pretty much everything, and so the language papers over what's really going on. That is, a java object.element is actually a C object->element. The language uses the dot because, well, why wouldn't you?

As to why it's so powerful … well, you will just have to grok it, I can't really justify it in words. The main thing about it that's powerful is the way that arrays and pointers work together.

And as to why you have to use it in wifi client, the answer is that that's the way the interface of the library was written, so there.

ductruong253:
I read some topics and they said that some languages such as Java or C/C++ now have "Automatic Memory Management" so the pointer is not nessesary.

Where did you read this? That's like saying modern cars have automatic transmissions so putting petrol into them is not necessary.

Delta_G:
Try this example and it will show you one good example of why we have it.

     Serial.println(addOneP(&b);

Close, but no cigar (or closing brace !)

econjack:
Any variable has two components to it after it is defined: 1) an lvalue, which is the memory address where the variable is located in memory, and 2) an rvalue, which is the content, or value, of the variable. For example, the statement:

void setup() 

{
  int val;
}



might be compiled so that the variable is located at memory address 650. The content of *val* is unknow because we have assigned anything to it.
![](http://i283.photobucket.com/albums/kk301/econjack/lvalue001.jpg)

What you have mentioned here has nothing to do with rvalues and lvalues. It is simply an objects value and its pointer. This is a terrible way to teach the concept as the compiler will use the terms lvalue and rvalue with an entirely differnt (and correct) meaning.

"int val;" can be either an lvalue or an rvalue depending on what type of expression you are writing. This has nothing to do with pointers.

A pointer can also be an rvalue and lvalue, still... nothing to do with pointers.

Well I think this is stage 1 of understanding - an intentionally simplified definition of what is an expression and what are lvalues and rvalues.

Initially when lvalues were defined for C, it literally meant "values suitable for left-hand-side of assignment". Later, however, when ISO C added the const keyword, this definition had to be refined because const values can't be changed later in the code. So the industry kept the l originally from left but gave a different meaning as locator.

From helicopter view, an lvalue (locator value) represents an object that occupies some identifiable location in memory i.e. has a very well known address - hence the connection to pointer. And now rvalues are defined by exclusion, by saying that every expression is either an lvalue or an rvalue. Thus an rvalue is an expression that does not represent an object occupying some identifiable location in memory.

This is a pretty crude high level view but the building principle

It explains the basics of

int var;
var = 10;       // OK
10 = var;       // ERROR!
(var + 1) = 10; // ERROR!

That's because An assignment expression expects an lvalue as its left operand, and var is an lvalue, because it is an object with an identifiable memory location. The other are invalid because the left operand (left often confused with the l of lvalue - remember it's locator now if you want to be smart in cocktail parties :slight_smile: ) do not represent lvalue (and thus by definition are rvalues)

lvalue and rvalue depends on context and lvalues can automatically be transformed in rvalues if the operator expects this.

int x = 1;         // x is an lvalue
int y = 2;         // y is an lvalue
int total = x + y; // the expression with + needs two rvalues, so x and y are automatically converted to rvalues, the operator is applied and an rvalue is returned. So the = operator which needs an lvalue and an rvalue gets the right thing.

The opposite conversion does not happen automatically though because an rvalue by definition can't be an lvalue. So the programmer needs to help express his intent to transform an rvalue into a lvalue and that is why the unary dereference operator * takes an rvalue argument but produces an lvalue as a resul and similarily, the unary address-of operator & takes an lvalue argument and produces an rvalue (in C++ it has also another role as it allows to define reference types called lvalue references - and constant lvalue references can be assigned rvalues, which makes possible to accept values by constant references into functions and to avoid unnecessary copying and construction of temporary objects).

The rest is in any good C reference manual and compiler theory books

J-M-L:
Well I think this is stage 1 of understanding - an intentionally simplified definition of what is an expression and what are lvalues and rvalues.

lvalue and rvalue depends on context

Yes,

Lvalues and Rvalues are what expressions are, not declarations. The whole explanation of an rvalue being a pointer and an lvalue being a value is plain incorrect if you choose to ignore the fact that a value is able to be an rvalue.. in an rvalue expression.

C++Standard:
— An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object

A pointer gained by using the addressof operator is a temporary, along with a literal (except strings). There is nothing specific about pointers here.

From helicopter view, an lvalue (locator value) represents an object that occupies some identifiable location in memory i.e. has an address - hence the connection to pointer.

The opposite conversion does not happen automatically though because an rvalue by definition can't be an lvalue. So the programmer needs to help express his intent to transform an rvalue into a lvalue and that is why the unary dereference operator * takes an rvalue argument but produces an lvalue

A dereferenced pointer is an entirely different expression to the pointers id-expression. To expect an rvalue -> lvalue conversion by expecting an implicit pointer->value conversion seems to show that you are thinking about rvalues 'being' pointers, and not expressions. A pointer can be an rvalue expression, but is not by definition. E.g.

char *c;

void setup() {
  c = nullptr;
}

Pointer 'c' is used only in lvalue expressions here!

With regards to a dereferenced pointer returning an lvalue, this is correct, but not a blanket rule.
The value could just as easily be an rvalue id-expression depending on its constness:

C++Standard:
Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue;

and

A glvalue (“generalized” lvalue) is an lvalue or an xvalue.

A dereferenced pointer is an entirely different expression to the pointers

I did not mention the word pointer. I just used lvalue and rvalue concepts

J-M-L:
I did not mention the word pointer. I just used lvalue and rvalue concepts

Yes you were pointing out the concepts. And its those concepts that matter.

I was more or less making stronger case against Econjacks post, as it seems you were replying to my post in which I made an argument against the explanation given by Jack. This gave me the impression you were making a case regarding "rvalues are pointers". But from your last post your stance on the l/rvalue concepts appears in agreement with what I have also mentioned (l/rvalues are types of expressions, not a property of an object).

Ok sorry for the confusion

Hi Nick Gammon,
Here you go: Nanyang Technological University , I got this from J-M-L answer.

Dear all,
As I said, I really new to programming, I just do the basic of Arduino programming. But I geartly appreciate about your helps.