#arrays #c #pointers #pass-by-reference #pointer-arithmetic
#массивы #c #указатели #передача по ссылке #указатель-арифметика
Вопрос:
void foo(int **arr)
{
**arr = 5; // works fine, no warnings and myArray[0] is 5 after call.
*(arr 5) = 5; //warning - assignment makes pointer from integer without a cast - why?
*(arr)[5] = 5; //No warnig but programm would crash
}
int main()
{
int *myArray = (int*)calloc(10,sizeof(int));
foo(amp;myArray); //no warning but myArray[5] would be still 0
foo(myArray); //warning - passing argument 1 of 'foo' from incompatible pointer type (but works fine)
printf("%d",myArray[5]);
return 0;
}
Как правильно передать массив в мою функцию и получить доступ к myArray[5] без каких-либо предупреждений?
Ответ №1:
Как написано, правильный способ индексирования в arr
будет
(*arr)[5] = 5;
Поскольку arr
это указатель на указатель на ваш массив, вы не хотите индексировать в arr
, вы хотите индексировать в то, на что arr
указывает. Вам нужно явно сгруппировать *
с arr
, поскольку постфиксные операторы типа []
имеют более высокий приоритет, чем унарные *
.
Сказав это, единственная причина передать указатель на myArray
— это если вы ожидаете изменить значение myArray
самого себя, например, с помощью вызова realloc
. Если это не является намерением, тогда лучше написать функцию, как показали Антти и Питер.
Ответ №2:
Поскольку foo
принимает указатель на указатель на целое число, вызов foo(amp;myArray)
здесь правильный. Но вам вообще не нужно этого делать. Просто передайте myArray
и foo
вместо этого возьмите указатель на int:
void foo(int *arr)
{
arr[5] = 5;
}
int main()
{
int *myArray = calloc(10, sizeof(int)); // no need to cast here unless compiling with a C compiler
foo(myArray);
printf("%d", myArray[5]); // prints 5
return 0;
}
Я знаю, что указатели могут сбивать с толку, но, похоже, здесь очень фундаментальное недоразумение, поэтому я рекомендую внимательно прочитать раздел указателей любого хорошего учебника по C еще раз.
Комментарии:
1. Спасибо. Я работал над своими знаниями о «указателе на указатель» и спросил себя, как работать с массивом в этом контексте. На слайде лекции было написано, что указатель на указатель используется для вызова по ссылке с массивами — поэтому я попробовал это, и это меня смутило. Спасибо, что помогли мне.
Ответ №3:
Вот так:
#include <stdio.h>
#include <stdlib.h>
void foo(int *arr) {
arr[5] = 5;
}
int main(void) {
int *myArray = calloc(10, sizeof(int));
foo(myArray);
printf("%d", myArray[5]);
}
Вам нужно передать указатель по ссылке только в том случае, если вы хотите изменить значение исходного объекта указателя (т. Е. Если вы хотите, чтобы указатель, сохраненный в, myArray
указывал на другой выделенный блок памяти после вызова foo
).