1

Why I can not increment the position of the pointer array?

typedef char SmallBuffer[20]; 
SmallBuffer sb2,  sb1 = "wtf!";

while(*sb1 !=  '\0'){ 
     .....
     ++sb1;
}  

when compiling the gcc compiler returns :

main.c:19:38:
error: lvalue required as increment operand
++sb1;

this happening for integer array too.

======= Update 1 =====

I tried in many other way (of-course as a pointer)

typedef char *String;
String a = "wtf!";
    while(*a != NULL){
        *a = TO_UPPER(*a); ++a;
    } printf("%s", a);

can anyone point me what's wrong in my code?

==== Update 2 =====

This code is from Stephen Kochan - Programming in C

Page- 311

while ( *string != '\0' )
{
*string = TO_UPPER (*string);
++string;
}

can anyone explain me this code? (i've been trying this shit for last 4 hours)

Gonzalez
  • 209
  • 1
  • 2
  • 8
  • 2
    There's no "pointer array", there are two arrays. Arrays are not pointers, and pointers are not arrays. – molbdnilo Aug 16 '16 at 11:13
  • You shouldn't hide arrays behind typedefs. Such code is hard to read and maintain. If you need a specific type for an array, consider using a struct instead. – Lundin Aug 16 '16 at 11:13

4 Answers4

3

In your code, sb1 represents an array variable name (array of type char[20]). An array variable name is not a modifiable lvalue. So, it cannot be used as the operand for pre-increment operator.

Related, quoting C11, chapter §6.3.2.1, (emphasis mine)

A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a constqualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a constqualified type.

and, for unary Prefix increment (and decrement) operators, chapter §6.5.3.1

The operand of the prefix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.


======= Update =====

In your second snippet, you're literally trying to modify a string literal, that's illegal and invokes undefined behavior.

Quoting C11 again, chapter §6.4.5/p7, String literals

[...] If the program attempts to modify such an array, the behavior is undefined.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • An array variable is not a _modifiable_ lvalue? (Or it would be an rvalue, which it is not. See e.g. [this Q&A](http://stackoverflow.com/questions/17687429/why-array-type-object-is-not-modifiable)). – dfrib Aug 16 '16 at 11:12
  • then how you move that's postion? – Gonzalez Aug 16 '16 at 11:37
  • @Gonzalez Well, to _move_ the position, you take a pointer, store the base address of the array to the pointer and do pointer math on the pointer, **not directly** on the array name (which decays to pointer to first element of the array, anyways). – Sourav Ghosh Aug 16 '16 at 11:38
  • @SouravGhosh please see the updated thread. – Gonzalez Aug 16 '16 at 11:54
  • @Gonzalez you should avoid updating a question that has been fully answered (and even dupemarked) with updates that totally changes and extends the question. In such cases, its better to simply ask a new question (this answer, I believe, fully answers your initial question). – dfrib Aug 16 '16 at 12:01
1

There are a few things you can increment in C++.

  1. Pointers

  2. Elementary integers.

Some things you can't increment by default, like classes, unless you implement what the increment operator means for them.

And there are some things you can never increment.

  1. Arrays.

sb1 is an array, in your code. You can't increment an array. That's a meaningless operation.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • then how do i move it? – Gonzalez Aug 16 '16 at 11:12
  • Move what? An array is a contiguous area of memory. "Move an array" is a logically meaningless statement. If you want to iterate over the values in an array, use a pointer. – Sam Varshavchik Aug 16 '16 at 11:13
  • @Gonzalez Use a separate pointer variable (see @Sanders answer) or use array indexing: `int i = 0; while (sb1[i] != '\0') { i++; }` – Klas Lindbäck Aug 16 '16 at 11:18
  • please see my updated code.. – Gonzalez Aug 16 '16 at 11:30
  • There are multiple problems with your "updated code". 1. A pointer constant, NULL, being compared with a character value. 2. There's no such library function called TO_UPPER in the C++ library. 3. After iteration the pointer ends up pointing to the end of the string, of course, and print() ing it only shows the end of the string, of course. Which is nothing. – Sam Varshavchik Aug 16 '16 at 11:35
  • I am referring to C++ also, and I already explained the reason for the error. What part of "arrays cannot be incremented" you didn't understand? – Sam Varshavchik Aug 16 '16 at 11:45
  • **i am not talking about c++** – Gonzalez Aug 16 '16 at 11:53
  • If you are not "talking about C++" then why did you add the `C++` tag to this question? – Sam Varshavchik Aug 16 '16 at 11:56
1

Arrays are not pointers. Pointers are not arrays. You have no pointers anywhere in the posted code.

Yet you attempt to use pointer arithmetic on an array, which is not allowed and does not make sense.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Pointer arithmetic can be used on an array. But not the increment operator or (compound) assignment operators. – M.M Aug 16 '16 at 12:14
1

Change your code to this and it will work:

typedef char SmallBuffer[20]; 
SmallBuffer sb2,  sb1 = "wtf!";
char* sbp1= &sb1[0];
while(*sbp1 !=  '\0'){
     sbp1++;
}

sb1 isn't an lvalue but sbp1 is. sb1 is an 'array' and sbp1 is a 'pointer'. Pointers aren't the same as arrays, arrays do contain a array and pointers do contain memory addresses which possibly point to a specific array. You can rise the memory address in the pointer variable but you can't rise the array.

Another possibility is to rise the index of the array like so:

typedef char SmallBuffer[20]; 
SmallBuffer sb2,  sb1 = "wtf!";
int i= 0;
while(*sb1[i] !=  '\0'){
     i++;
}

======= Update =====

For your update; I've simplified your code a little bit to explain why it doesn't work, I also added some comments:

char* a = "wtf!"; //Create pointer 'a' and assign the memory address of the first letter of the constant char array "wtf!" to it
while(*a != NULL){
    *a = TO_UPPER(*a); //Write the uppercase of *a to the constant char which is positioned at memory place 'a'
    ++a;
}

You want to write to a constant char which isn't possible because the char is constant (logically).

You can solve the problem by making the char array "wtf!" not constant like so;

char stringArray[]="wtf!";
char* a = &stringArray[0]; 
while(*a != 0){
    *a = TO_UPPER(*a); 
    ++a;
}
printf("%s", stringArray);

Or including the typedef:

typedef char *String;
char stringArray[]="wtf!";
String a = &stringArray[0]; 
while(*a != 0){
    *a = TO_UPPER(*a); 
    ++a;
}
printf("%s", stringArray);

In this code I assume you have made a function 'TO_UPPER'. I also changed the 'printf line'. printf("%s", a) wouldn't have printed anything because the pointer is rised so it points to the terminating 0 at the end of the string. Also I replaced 'NULL' by 0. I assume you want to stop at the end of the string. Strings are terminated by a 0. 'NULL' is a keyword for another purpose.

======= Update 2=====

For your update2; You didn't include the whole code. The coded snipped will work perfectly fine if you add some lines in front of it like so;

char stringArray[] = "wtf!";
char* string = &stringArray[0];
while ( *string != '\0' )
{
    *string = TO_UPPER (*string);
    ++string;
}

But I can recommend you to not use 'string' as a variable name because it's somewhat confusing for other persons like here on StackOverflow. In c it's fine but in c++ 'string' is a keyword for a char array.

Sander
  • 171
  • 1
  • 10