Изменение массива с функцией в C? - PullRequest
14 голосов
/ 10 апреля 2011

Я хочу вызвать функцию и хочу, чтобы эта функция изменила содержимое строки или массива в программе на константу.

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 ]

30 голосов
/ 10 апреля 2011

Вы передаете указатель на массив по значению, а не по ссылке. Должно быть:

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;
}

Вы передали адрес "hello" функции changeArray, но в функции вы изменили переданное значение, а не исходный указатель. Внесенное мной изменение передает адрес указателя, а сам указатель изменяется в функции.

Пожалуйста, не char *blah = "hello"; определяет указатель на постоянную строку, а также *arr = "bingo";, это нормально, но если вы решите изменить саму строку, вы не сможете.

EDIT:

Когда вы передаете аргумент, даже указатель, в функцию, вы фактически копируете его в какое-то место, где функция читает его оттуда (обычно в стек). Вы передаете не сам аргумент, а его копию. Когда функция изменяет ее (как в 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 и в функции, которую мы говорим: « content arr - это address , перейдите по этому адресу и измените его содержимое так, чтобы оно указывало на строку «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...)

Надеюсь, я вас не смутил ...

6 голосов
/ 10 апреля 2011

В вашем коде нет массивов. Если вы на самом деле пытаетесь изменить то, на что указывает указатель вашего бла-символа, вам нужно передать указатель на указатель в функцию. Однако, если вы хотите сделать это с помощью массивов, вам нужно сделать что-то вроде:

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;
}
0 голосов
/ 10 апреля 2011

Вам нужно передать указатель на массив, а не на сам массив.

Другое дело: добавьте условие управления в вашу функцию.подумайте: что произойдет, если «бинго» будет больше, чем strlen (some_array)?это даст вам ошибку, потому что в C вы должны использовать malloc, если вам нужен динамический размер массива!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...