0

I am not understanding why this code is wrong, it says lvalue required as increment operand. But isn't planets an array of pointers to strings? so isn't planets++ supposed to take me to the next string. example- planets is a pointer to the string "mercury". When I do planets++ shouldn't it take me to "venus"

#include <stdio.h> int main() { char* planets[] = {"Mercury", "Venus", "Earth","Mars","Jupiter", " Saturn", "Uranus", "Neptune", "Pluto"}; int count = 0; for(planets; planets <= planets + 8;planets++){ if(**planets == 'M'){ count++; }// if }// for printf("\n%d",count); } 
4
  • 2
    "...isn't planets an array of pointers to strings?" - Yup, stress the first part of that description; it's an array. This is a not-quite-textbook example of how arrays aren't pointers.. That increment operation makes no sense. Commented Oct 27, 2019 at 5:57
  • @Saadman, is the space in front of Saturn intentional? Commented Oct 27, 2019 at 6:19
  • I think I got confused because when we pass pointers as function parameters we are allowed to use the array name as the pointer and change it. Because since arguments passed to functions are protected against change, it works in that case. I think that might be the diff Commented Oct 27, 2019 at 7:01
  • planets is an array of pointers to strings. thus, if(**planets == 'M') is wrong. You might need another pointer which points to the pointer array planets. Note **planets is a pointer named planets to another pointer, which isn´t the case here. Commented Oct 27, 2019 at 12:08

4 Answers 4

3

Your description of planets is accurate; it's defined as an array of pointers. Stress the array part of that, because that means using its id is disqualified for lvalue operations like post-increment.

If you want to walk that array of pointers using pointer notation, it can be done using a proper pointer-to-pointer keyed to the type of the array. If the array is an array of const char*, then a pointer to const char * (i.e. a const char **) is appropriate.

Like this:

#include <stdio.h> int main() { const char *planets[] = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" }; int count = 0; for(const char **p = planets; p != planets + 9; ++p) { if(**p == 'M'){ count++; }// if }// for printf("%d\n",count); } 

Output

2 
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for your answer. As far as I knew arrays are the same as pointers right? So Why can't I just use the array name as pointer and move through? Also, I am quite new to pointers, so its confusing me. Suppose, we declare a 2 dimentional array int B[2][3] . So doing the following will give me a compilation error right? int* p = B; But i read in my textbook, that we can int(p) [3] = B; and it would be correct? So for my planets code, could I have written the following: Instead of char** planet = planets; can i write char* planet [8] = planets; ? and can you explain the diff?
@SaadmanIslamKhan They're not the same as pointers. When their id is used in the appropriate expression context, their id converts to a temporary pointer-to-type (most call it "decaying", but I prefer not to if for no other reason than because the language standard doesn't). An example of such conversion is in the init construct of the for loop of this answer, btw.
Suppose, we declare a 2 dimentional array int B[2][3] . So doing the following will give me a compilation error right? int* p = B; But i read in my textbook, that we can int(p) [3] = B; and it would be correct? So for my planets code, could I have written the following: Instead of char** planet = planets; can i write char* planet [8] = planets; ? and can you explain the diff? ^can you answer this please?
@SaadmanIslamKhan given a 2D array (use the term "array of arrays, because that's exactly what a real 2D array is), int arr[2][3]; then an appropriate pointer type to initialize with just the array id would be int (*p)[3] = arr;
So for the planets, if we had used array index to loop through, it would look like this,planents[0][i], so this is also a 2d array. So wouldn't an approriate pointer type to initialize with just the array id be char (*p)[8] = planets;? char *planets[] = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" }; could this not be written as char planets[9][8] ={ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" };
|
1

The variable planets is an array so you can't increment it.

Instead use an integer as index in the loop:

#include <stdio.h> int main() { char* planets[] = {"Mercury", "Venus", "Earth","Mars","Jupiter", " Saturn", "Uranus", "Neptune", "Pluto"}; int count = 0; for(int i = 0; i < 9; i++){ if(planets[i][0] == 'M'){ count++; }// if }// for printf("\n%d",count); } 

Comments

1

As stated in the other answers, char *planets[] defines a an array of strings. The compiler will consider planets as a label afixed to the array, and will (generally) not allow that label to be moved. So, the best options are (as shown in the other answers here) to index through the array, or use an auxiliary pointer to walk the array.

I like to add an ending NULL to arrays, which provides a stopping point when walking them with an auxiliary pointer. For example:

 #include <stdio.h> int main() { char *planets[] = {"Mercury", "Venus", "Earth","Mars","Jupiter", " Saturn", "Uranus", "Neptune", "Pluto", NULL}; char **planet; int count = 0; for(planet = planets; *planet; planet++) { if(**planet == 'M') count++; } printf("%d\n",count); } 

2 Comments

Thank you for your answer. As far as I knew arrays are the same as pointers right? So Why can't I just use the array name as pointer and move through? Also, I am quite new to pointers, so its confusing me. Suppose, we declare a 2 dimentional array int B[2][3] . So doing the following will give me a compilation error right? int* p = B; But i read in my textbook, that we can int(p) [3] = B; and it would be correct? So for my planets code, could I have written the following: Instead of char* planet = planets; can i write char* planet [8] = planets; ? and can you explain the diff?
@SaadmanIslamKhan, This link might help clear your mind about pointers.
0

regarding:

for(planets; planets <= planets + 8;planets++){ 

this results in the following message from the compiler:

:11:48: error: lvalue required as increment operand 

However, the variable planets is located at the address, fixed in memory, so cannot be changed. Suggest

for( char *string = planets; string <= planets+8; string++ )

then use the variable string within the body of the for() loop

3 Comments

Thank you for your answer. As far as I knew arrays are the same as pointers right? So Why can't I just use the array name as pointer and move through? Also, I am quite new to pointers, so its confusing me. Suppose, we declare a 2 dimentional array int B[2][3] . So doing the following will give me a compilation error right? int* p = B; But i read in my textbook, that we can int(p) [3] = B; and it would be correct? So for my planets code, could I have written the following: Instead of char* planet = planets; can i write char* planet [8] = planets; ? and can you explain the diff?
Actually and array is NOT a pointer. However, referencing an array name results in the address of the first byte of the array
The array cannot be moved. So need to use a different variable to step through the array (or access the array via planets[0] ... planets[8]

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.