gcc 4.4.4
What am I doing wrong?
char x[10];
char y[] = "Hello";
while(y != NULL)
*x++ = *y++;
Many thanks for any advice.
x++ is the short form of x = x + 1. However, x here is an array and you cannot modify the address of an array. So is the case with your variable y too.
Instead of trying to increment arrays, you can declare an integer i and increment that, then access the i'th index of an arrays.
char x[10], y[5] = "Hello";
int i = 0;
while (y[i] != 0)
{
x[i] = *y[i];
i++;
}
x[i] = 0;
Most likely you fell victim to a popular misconception that "array is a pointer", i.e. when you define an array what you actually get is an ordinary pointer that points to some block of memory allocated somewhere. In your code you are making an attempt to increment that pointer.
The code does not "work" because in reality arrays are not pointers. Arrays are arrays. Arrays cannot be incremented. There's no such operation as "increment an array" in C language. In fact, arrays by themselves in C are non-modifiable lvalues. There are no operations in C that can modify the array itself (only individual elements can be modifiable).
If you want to traverse your arrays using the "sliding pointer" technique (which is what you are actually trying to do), you need to create the pointers explicitly and make them point to the starting elements of your arrays
char *px = x;
char *py = y;
After that you can increment these pointers as much as you want.
Arrays in C are indeed pointers, but constant pointers, which means after declaration their values can't be changed.
int arr[] = {1, 2, 3};
// arr is declared as const pointer.
(arr + 1) is possible but arr++ is not possible because arr can not store another address since it is constant.
char x[10];
char y[] = "Hello";
char *p_x = &x[0];
char *p_y = &y[0];
while(*p_y != '\0') *p_x++ = *p_y++;
Since you can't modify the array addresses (done by x++ and y++ in your code) and you can modify the pointer address, I copied over the address of the array into separate pointers and then incremented them.
If you want, I'm sure you can reduce the notation, but I hope you got the point.
x and y are arrays, not pointers.
They decay into pointers in most expression contexts, such as your increment expression, but they decay into rvalues, not lvalues and you can only apply increment operators to lvalues.
At most times, array just like a pointer.
Just remember you can't modify array!
And y++ is y = y + 1.
char y[] = "Hello";
So you do modify array when you y++!!
It will produce error: lvalue required as increment operand.
We can not modify a array name, but What about argv++ in f(int argv[])?
Quotes from K&R in p99 “an array name is not a varible; construction like a = pa and a++ are illegal" which says the name of an array is a synonym for the location of the initial element.”
But why in function parameter func(char *argv[]), we can do argv++ despite of argv is a array name.
And in int *a[10], we can't do the a++ like argv++.
The name of array is a synonym for the location of the initial element. ---K&R
arrayname++ is illegal.
In function parameter, such as char *argv[], it is the same as char **argv. type *arrayname_para[] in parameter is a another synonym for type **arrayname_para.
Since you've defined both x and y as arrays, you can't modify them. One possibility would be to use pointers instead:
char x[10];
char *xx = x;
char *y = "Hello";
while (*y != '\0')
*xx++ = *y++;
Note that I've also fixed your termination condition -- a pointer won't become NULL just because it's reached the end of a string.
Array is a static continuous block of allocated memory. Array names are immutable references to the first block memory. An attempt to increment the address (referenced by name of array) would result in loss (better to say deference) of other memory locations. Say we have array
int p[]={10,20,30}
Here p (by design) refers to index 0. Say somewhere we increment p as :
p++
Assuming increment to be allowed would result in p to point to index 1. Now thinking what p[1]=?
p[1] would then translate to dereferencing the value one place to the right of the current p location
Or location p[2] for original array.
Do this repeatedly and soon tracking the array indices would become very troublesome.
So to avoid such mishaps array names(lvalues) addresses are immutable.
Another concept is word addressing and byte addressing:-
Character Arrays(string) in C are byte addressable instead of being word addressable. So if we have an array
int a[]={10,20,30}
printf("%d",*(a+1)) //Ouput:20 (int is word addressable)
printf("%d",*(++a)) // Error: Array references are immutable
int* cpya=a;
printf("%d",*(++cpya)) /* Output:20 (cpy is not array reference but a copy. Hence is Mutable) */
char b[]="Hello"
printf("%c",*(++b)) // Error : Array references are immutable
printf("%c",*(b+1)) /* undefined_behavior as character Array(strings) are byte addressable and not word addressable */
printf("%c",*(b+sizeof(char)*1)) // Output :e (It's byte addressable).
Arrays are constant pointers. We can't change them.
int q;
int *const p = &q;
p = NULL; // this is not allowed.