gcc 4.4.4
Что я делаю неправильно?
char x[10];
char y[] = "Hello";
while(y != NULL)
*x++ = *y++;
Большое спасибо за любой совет.
gcc 4.4.4
Что я делаю неправильно?
char x[10];
char y[] = "Hello";
while(y != NULL)
*x++ = *y++;
Большое спасибо за любой совет.
x++
- краткая форма x = x + 1
. Однако x
здесь представляет собой массив, и вы не можете изменить адрес массива. Так происходит и с вашей переменной y
.
Вместо того, чтобы пытаться увеличивать массивы, вы можете объявить целое число i
и увеличить его, а затем получить доступ к i
'-му индексу массивов.
char x[10], y[5] = "Hello";
int i = 0;
while (y[i] != 0)
{
x[i] = *y[i];
i++;
}
x[i] = 0;
Скорее всего, вы стали жертвой популярного заблуждения, что "массив является указателем", т.е. когда вы определяете массив, что вы на самом деле получаете, это обычный указатель, который указывает на какой-то выделенный блок памяти. В вашем коде вы пытаетесь увеличить этот указатель.
Код не работает, потому что на самом деле массивы не являются указателями. Массивы - это массивы. Массивы не могут увеличиваться. Там нет такой операции, как "приращение массива" на языке C. На самом деле, массивы сами по себе в C не являются модифицируемыми lvalues. В C нет операций, которые могут изменять сам массив (только отдельные элементы могут быть модифицируемыми).
Если вы хотите пересечь свои массивы с помощью техники "скользящего указателя" (именно этого вы и пытаетесь сделать), вам нужно явно создать указатели и указать их на начальные элементы ваших массивов.
char *px = x;
char *py = y;
После этого вы можете увеличивать эти указатели столько, сколько хотите.
char x[10];
char y[] = "Hello";
char *p_x = &x[0];
char *p_y = &y[0];
while(*p_y != '\0') *p_x++ = *p_y++;
Поскольку вы не можете изменить адреса массивов (сделанные x++
и y++
в вашем коде), и вы можете изменить адрес указателя, я скопировал по адресу массива в отдельные указатели и , затем увеличили их.
Если вы хотите, я уверен, что вы можете уменьшить обозначение, но я надеюсь, что вы поняли.
Массивы в C действительно являются указателями, но постоянными указателями, что означает, что после объявления их значения не могут быть изменены.
int arr[] = {1, 2, 3};
// arr is declared as const pointer.
(arr + 1)
возможен, но arr++
невозможен, поскольку arr
не может сохранить другой адрес, поскольку он является постоянным.
x
и y
- массивы, а не указатели.
Они распадаются на указатели в большинстве контекстов выражения, таких как выражение increment, но они распадаются на rvalues, а не lvalues, и вы можете применять только приращения операторов к lvalues.
Поскольку вы определили как x
, так и y
как массивы, вы не можете их изменять. Одной из возможностей было бы использовать указатели вместо этого:
char x[10];
char *xx = x;
char *y = "Hello";
while (*y != '\0')
*xx++ = *y++;
Обратите внимание, что я также исправил условие завершения - указатель не станет NULL
только потому, что он достиг конца строки.
В большинстве случаев массив точно так же, как указатель.
Просто помните, что вы не можете изменять массив!
И y++
- y = y + 1
.
char y[] = "Hello";
Итак, вы изменяете массив, когда вы y++
!!
Он произведет error: lvalue required as increment operand
.
Мы не можем изменить имя массива, но как насчет argv++
в f(int argv[])
?
Цитаты из K & R в p99 "имя массива не является varible, конструкция вроде a = pa
и a++
являются незаконными", в которых говорится, что имя массива является синонимом расположения исходного элемента. "
Но почему в параметре функции func(char *argv[])
мы можем сделать argv++
, несмотря на argv
имя массива.
И в int *a[10]
мы не можем сделать a++
как argv++
.
Имя массива является синонимом расположения исходного элемента. --- K & R
arrayname++
является незаконным.
В параметре функции, например char *argv[]
, он совпадает с char **argv
. type *arrayname_para[]
в параметре является другим синонимом для type **arrayname_para
.
Массивы являются постоянными указателями. Мы не можем их изменить.
int q;
int *const p = &q;
p = NULL; // this is not allowed.