Pages: [1]   Go Down
Author Topic: sizeof operator  (Read 1395 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have an interger array:
int LetterA[] = {3,7,9,11,15,16,17,18,19,20,21,25,26,30};

And, I pass it to a function:
Show(50,LetterA);

Here is the function:
void Show (int Timer, int pins[]) {
  int count1;
  int count2;

  for (count1 = 0; count1 < Timer; count1++) {
    for (count2 = 0; count2 < sizeof(pins); count2++) {
      TurnON(pins[count2]);
      delay(1);
      TurnOFF(pins[count2]);
    }
  //}
}

the sizeof(pins) command is not working, it seems to always return 2.  Am I using the sizeof operator incorrectly?  I'd like to get the number of objects in the array, in this case, 14.

Thanks,
lucas
Logged

New Zealand
Offline Offline
God Member
*****
Karma: 0
Posts: 999
Arduino pebbles
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Am I using the sizeof operator incorrectly?
Short answer, yes. (Heh, almost got caught by double negatives... :-) )

There's two issues with your approach, one is how you're using the sizeof operator, and the other is how you're trying to determine the number of elements.

"The sizeof operator is a compile-time operator..."--this means that the value is set once when the program is compiled, and doesn't change when the program is running.

You might want to search online for answers to how to find the number of elements of an array in C. (Or wait for someone else to post a reply that says more. :-) )

--Phil.
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi lucas, as Phil says, sizeof is a compile time operator that returns the number of elements that have been declared in variable.

sizeof(pins) is returning 2 because pins is a variable that is a pointer to an array. A pointer on the Arduino is two bytes long no matter how big the array it points to.

One way of getting your code to work is to define a constant for the size of your array:

  #define LETTER_LEN  14
  int LetterA[LETTER_LEN] = {3,7,9,11,15,16,17,18,19,20,21,25,26,30};

Putting the constant in the declaration is optional but has the advantage that the compiler will tell you if you have not given enough initialisers.

If the arrays are passed to Show are the same size you can then do:
 for (count2 = 0; count2 < LETTER_LEN ; count2++)  
If they vary in length then you could pass the length to the function along with the array pointer

I hope that helps
« Last Edit: February 29, 2008, 02:56:47 am by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That makes sense, but I'm confused because the example shows the operator being used in a for loop.  The only difference that I can see is that mine is in another function.

---Example---
char myStr[] = "this is a test";
int i;
void loop() {
  for (i = 0; i < sizeof(myStr) - 1; i++){
    Serial.print(i, DEC);
    Serial.print(" = ");
    Serial.println(myStr, BYTE);
  }
}

lucas
Logged

London
Offline Offline
Faraday Member
**
Karma: 8
Posts: 6240
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is the only difference, but it is a very significant one!

If you take the sizeof an array directly you will get the size. But if you pass that array to a function in the C language, it actually passes a pointer to the array. So sizeof in the function returns the size of the pointer (two bytes in the arduino). The pointer is actually pointing to the first chracter in the array so if you take the size of what the array pointer is pointing to (in C that is: *array) that will be the size of one element in the array.

I have added some code to your example to illustrate this.

Code:
char myStr[] = "this is a test";
int i;

void setup(){
  Serial.begin(19200);
}

void Test(char *Str){
  int size = sizeof(Str);
  Serial.println(size);      // prints 2,this is the size of a pointer to a char array
  size = sizeof(*Str);        
  Serial.println(size);      // prints 1, this is the size of the character that the string pointer Str points to ( the first char in the array)

}

void loop() {  
  
  for (i = 0; i < sizeof(myStr) - 1; i++){
    Serial.print(i, DEC);
    Serial.print(" = ");
    Serial.println(myStr[i], BYTE);
  }
  
  i = sizeof(myStr);   // set i to be the size of the array
  Serial.println(i);   // prints 15
  Test(myStr);
  myStr[3] = 0;  // string now has 3 printable characters
  Serial.println(myStr);  // this will print 'thi'
  i = sizeof(myStr);      
  Serial.println(i);      // this prints 15 (the array is still 15 chars long    
  Test(myStr);            // test will be the same (i,e prints 2 because this is the size of the parameter passed
  delay(10000);
}

The most reliable way around this is to pass an additional parameter to your functions that contains the size of the variable you are passing.

Code:
void Test2(char *Str, int length ){
  int size = sizeof(Str);
  Serial.println(size);      // prints 2,this is the size of a pointer to a char array
  size = sizeof(*Str);        
  Serial.print(size);      // prints 1, this is the size of the character that the string points to, the first char in the array
  Serial.println(length);  // prints the length passed
}

usage:  
  Test2(myStr, sizeof(myStr));  // this passes 15 to test2
  Test2(myStr, strlen(myStr));  // this will pass the actual number of non null characters, this may be a smaller number than the above
  
« Last Edit: March 01, 2008, 04:22:24 am by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome.  I understand now.  Thanks very much for your help.

lucas
Logged

Pages: [1]   Go Up
Jump to: