Изменение массива с помощью функции в 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, если вам нужен динамический размер массива!

Другие вопросы по тегам