What does the & before a variable

Good day,

I have a doubt about a function. I can not explain what does the &swp

I think you do not to try to understand all the function. This function is used to calculate the Soil Water Potention (swp) of the soil crop.

I need some parameter

  • analog pin used to read the value
  • a pin to power the sensor
  • a delay (Not done yet)
  • the temperature of the soil

The calculated value is store in swp

int16_t val2 = 0;
read(14,10,5000,24,val2);
Serial.println(val2)

It's work, but I can not explain why I need to have & before swp in the bellow function.
Is to make sure to have a pointer at the begining of the variable, but I do not need to do the same for Tsoil.
The difference between Tsoil and swp, swp is used to return a calculated value

bool EcoIrrigation::read(int analogPin, int powerPin, unsigned long timeout, int16_t Tsoil, int16_t &swp)
{
  read(analogPin, powerPin, timeout, Tsoil, swp, false);
}

bool EcoIrrigation::read(int analogPin, int powerPin, unsigned long timeout, int16_t Tsoil, int16_t &swp, bool debug) // , bool debug = false
{
/*
  * TODO: Add the timeout
  */
	if(debug)
    Serial.println(F("\tPowering the Watermark sensor"));
	digitalWrite(powerPin, HIGH);
	if(debug)
    Serial.println(F("\tNeed a delay for the sensor to be in equilibre with the soil."));
	delay(3000);


	int highInput, lowInput;             		  // Store high and low time of wave in microseconds
  float totalInput;                     		// Temp store of total time of duration for one cycle of high and low pulse
  float frequency;                      		// calculated freqency   1/total time of one cycle.
  int16_t swp_shock;							         // store the swp calculate with Shock
  int percent=0;
  int32_t wrm;								              // Resistance of the sensors calculate from the frenquency returned by EcoIrrigation board output
    //int32_t wrm2;

  highInput = pulseIn(analogPin,HIGH);
  lowInput  = pulseIn(analogPin,LOW);
  totalInput = highInput + lowInput;

  frequency = 1000000 / totalInput;


  if (highInput >0 && lowInput>0)
  {
    if(debug)
      Serial.print(F("\tFrequency: ")); Serial.print((int16_t)frequency); Serial.print(F("Hz\t"));
  }
  else
  {
    if(debug)
      Serial.print(F("\tfrequency: Error "));
    return false;
  }
    
  delay(100);

  if(debug)
    Serial.println(F("\tPowering OFF the Watermark sensor"));
	digitalWrite(powerPin, LOW);
	delay(500);



	/*
	* Calculate the resistance in the soil
	*/
  if(debug)
    Serial.println(F("\tCalculate the resistance of the sensor with measured frenquence (LMC555 Time)"));
	
  resistanceCalc(frequency, wrm);					// Get the resistance of the sensors from the frequemcy
  wrm = constrain(wrm,550,27950);					// Contrain de value from the minimum
  
  if(debug)
  {
    Serial.print(F("\tWRM: "));
    Serial.print(wrm); Serial.print(F(" Ohm"));
  }

  /*
  * Calculation of the Soil Water Potetial
  */
  swp=0;
  // The temperature of te soil is needed. If that value does not exist, the scriot consider a temperazure of 24°C
  if(Tsoil == NULL)
  {
    if(debug)
      Serial.println(F("Tsoil is NULL"));
    Tsoil = 24;
  }

  if(debug)
  {
    Serial.print(F("DEBUG Tsoil: "));
    Serial.println(Tsoil);
  }

  
  /*
  * Converion following a table provided by the manufacturer
  */
  kPaCalc(wrm, Tsoil, swp, debug);
  Serial.print(F("\tSWP: ")); Serial.print(swp); Serial.println(F(" kpa"));

        
  /*
  * Converion with the equation of shock
  * We do not use it any more to calcuate the SWP as we use the table provided by the manufacturer.
  * But I keep it to compare the value or for a future need
  */
  swp_shock = kPaCalc_shock(wrm,Tsoil);											// Conversion with the Shock
  swp_shock = constrain(swp_shock,0,200);
  
  if(debug)
  {
    Serial.print(F("SWPs: ")); 
    Serial.print(swp_shock); 
    Serial.println(F(" kpa (Shock)"));
  }
  return true;


}

Many thanks

&

https://www.arduino.cc/reference/en/language/structure/pointer-access-operators/reference/

The & before the name of a variable indicates that the value of the corresponding variable that is being passed to the function may be changed by the function. This is known as passing by reference.

Without the & only the value of the variable is passed, known as passing by value, and the function will not change the value of the actual variable passed to the function

In a function’ parameter definition or variable definition, …

(Otherwise it’s the address of the variable or a bitwise and depending on context.)

Yes, swp will be changed by the function

I am confused with this terminology. With my word, I passed a value of swp, which is 0 before the function is called.
The value is calculated in the fonction and a new value is returned.

I would say, this are parameter definitions

  • analog pin used to read the value
  • a pin to power the sensor
  • a delay (Not done yet)
  • the temperature of the soil

and swp is a variable definition :upside_down_face:

if you define a function like this

void func(int & x) {
  x = 3;
} 

and call it this way

int y = 22;
f(y);
// now y is 3

because you passed y by reference so the function is modifying the original variable

if you had defined

void func(int x) {
  x = 3;
} 

and call it this way

int y = 22;
f(y);
// now y is still 22

you did not modify the original variable. the x that gets modified is the local variable for the function. (you passed 22 by value, so x initially was 22, then got modified to 3 and then got lost because it was a temporary variable (and the compiler likely got rid of the call because it had no side effects)).

so that's when a parameter of a function is passed by reference.

now if you had defined

void func(int* x) {
  *x = 3;
} 

then your function expects a pointer to an int variable. you would call it this way

int y = 22;
f(&y);
// now y is still 3

Note the & in front of the variable y in the call. Here the & means take the address of the y variable and pass that to the function.

& can also be a bitwise operator.

uint32_t x = 0xDEADBEEF;
uint32_t mask = 0b1111;
uint32_t y = x & mask;

here the & before the variable mask is a bitwise AND

1 Like

Dear J-M-L
I just found a explication on google and I quickly read your reply.
Many thanks. I have to leave but I will carefull read your interresting reply later in the evening.
See you

By having the &swp parameter, the EcoIrrigation function can read or modify your swp variable.
The read function's swp parameter gets it value from Ecoirrigation's &swp parameter.

It is not swp that will be changed, rather it is the variable used when the function is called. You could name the variable anything that you like in the function and it would still be the original variable that would be changed

Try this

void setup()
{
  Serial.begin(115200);
  byte byteA = 0;
  test(byteA);
  Serial.println(byteA);
}

void loop()
{
}

void test(byte &byteB)
{
  byteB++;
}

I was answering in the context of the question, but in any case in a function parameter's definition is it not the address of the variable and it can't be a bitwise and in that context anyway

yes - I was just adding more info as the title of the post is very generic " What does the & before a variable"

Touché !

but you were right that he later said "I can not explain what does the &swp" so your answer was indeed in context.

I was trying to make the post more interesting for future readers :slight_smile:

Thanks for all of your discussion!

@UKHeliBob
I am facing difficulties to understand the logic of your program of post #10 though it works!

1. From the calling point, you are passing the value (0) of the actual argument/parameter (byteA). It should be logically received by a normal variable (the formal parameter) of the called program. This is what is called parameter passing "by value". (Instead, you have received it in way that is beyond my understanding!)

2. You could pass the address of the actual parameter and receive it by the called program using a pointer variable. This is what is called argument passing "by reference". And accordingly, I would like to see you sketch of post #10 as follows:

void setup()
{
  Serial.begin(115200);
  byte byteA = 0;
  test(&byteA);    //actual argument is an address
  Serial.println(byteA); //shows: 1
}

void loop()
{
}

void test(byte *byteB)  //formal argument is a pointer variable
{
  ++(*byteB);   //increase the content of location being pointed by byteB
}

That's pretty much what his sketch does, but instead of using a pointer, he used a reference - the C++ way.

But, the programming begins with C and then C++.

What does that mean?

But, the programming (school) begins with C and then C++.