Изменение массива с помощью функции в C?
Я хочу вызвать функцию, и я хочу, чтобы эта функция изменила содержимое строки или массива в программе на константу.
Psuedocode:
some_array = "hello"
print some_array #prints "hello"
changeArray(some_array)
print some_array #prints "bingo"
Я знаю, что должен передать указатель на эту функцию. Вот что я написал,
void changeArray(char *arr){
arr = "bingo";
}
int main(int argc, const char* argv[]){
char *blah = "hello";
printf("Array is %s\n",blah);
changeArray(blah);
printf("Array is %s\n",blah);
return EXIT_SUCCESS;
}
Как я могу это сделать?
3 ответа
Вы передаете указатель на массив по значению, а не по ссылке. Так должно быть:
void changeArray(char **arr){
*arr = "bingo";
}
int main(int argc, const char* argv[]){
char *blah = "hello";
printf("Array is %s\n",blah);
changeArray(&blah);
printf("Array is %s\n",blah);
return EXIT_SUCCESS;
}
Вы дали адрес "привет" changeArray
функция, но в функции вы изменили переданное значение, а не исходный указатель. Внесенное мной изменение передает адрес указателя, а сам указатель изменяется в функции.
Пожалуйста не char *blah = "hello";
определяет указатель на постоянную строку, а также *arr = "bingo";
Это нормально, но если вы решите изменить саму строку, вы не сможете.
РЕДАКТИРОВАТЬ:
Когда вы передаете аргумент, даже указатель, функции, вы фактически копируете его в какое-то место, где функция читает его оттуда (обычно в стек). Вы не передаете сам аргумент, а его копию. Когда функция изменяет его (как в arr = "bingo";
) он изменяет копию переменной, а не исходную переменную. Таким образом, чтобы изменить саму переменную, мы передаем адрес переменной в функцию (changeArray(&blah);
- &
средства address of-
) и в функции мы модифицируем переменную, сохраненную в адресе, который мы передали (*arr = "bingo";
- *
означает переменную в адресе arr
).
Предполагая оригинал blah
указатель находится по адресу 0x00000000 и содержит адрес "hello"
строка которая например 0x00000010. если вы пройдете blah
в функцию, вы копируете ее в новую переменную, arr
, который расположен по адресу 0x00000020 например
Variable Address content
-------------------------------
blah 00000000 00000010 (points to hello)
"hello" 00000010 "hello" (this is just an example, so don't be hard on me :) )
arr 00000020 00000010
"bingo" 00000030 "bingo" (and again...)
Теперь, если вы измените содержание arr
Вы изменяете значение в адресе 0x00000020, но не значение в адресе 0x000000000, поэтому blah
все еще содержит 00000010.
Variable Address content
-------------------------------
blah 00000000 00000010 (points to hello)
"hello" 00000010 "hello" (this is just an example, so don't be hard on me :) )
arr 00000020 00000030 (points to "bingo")
"bingo" 00000030 "bingo" (and again...)
Вместо этого мы копируем адрес blah
, что 0x00000000, до arr
и в функции мы говорим - " содержимое arr является адресом, перейдите по этому адресу и измените его содержимое так, чтобы оно указывало на строку"bingo"". так что теперь содержимое по адресу 0x00000000 (что blah
) указывает на "бинго".
Variable Address content
-------------------------------
blah 00000000 00000030 (points to "bingo")
"hello" 00000010 "hello" (this is just an example, so don't be hard on me :) )
arr 00000020 00000000 (points to `blah`)
"bingo" 00000030 "bingo" (and again...)
Надеюсь, я вас не смутил...
В вашем коде нет массивов. Если вы на самом деле пытаетесь изменить то, на что указывает указатель вашего бла-символа, вам нужно передать указатель на указатель в функцию. Однако, если вы хотите сделать это с помощью массивов, вам нужно сделать что-то вроде:
void changeArray(char arr[]) {
// or you can use char *arr, it's the same thing from
// the C compiler's point of view
strcpy(arr, "blah");
// alternatively, you could set each element. i.e. arr[0] = 'b';
}
int main (int argc, char** argv) {
char blah[100] = "hello"; // this is an array
printf("Array is %s\n", blah);
changeArray(blah); // array decays to pointer
printf("Array is %s\n", blah);
return EXIT_SUCCESS;
}
Вам нужно передать указатель на массив, а не на сам массив.
Другое дело: добавьте условие управления к вашей функции. подумайте: что произойдет, если "бинго" будет больше, чем strlen(some_array)? это даст вам ошибку, потому что в C вы должны использовать malloc, если вам нужен динамический размер массива!