Несколько вещей:
Первый,
int *amount = 9;
не делает то же самое, что
*amount = 9;
В первом случае *
указывает только на то, что amount
имеет тип указателя, и мы инициализируем значение указателя (т. е. адрес) равным 9
, что, скорее всего, не является допустимым значением указателя. , и попытка разыменовать его может привести к ошибке времени выполнения.
Во втором случае мы присваиваем целочисленное значение 9
объекту, на который указывает amount
.
Почему это не сломалось, когда вы передали amount
в printf
? По сути, вы вызвали неопределенное поведение, передав аргумент неправильного типа (%d
ожидает int
, вы передали int *
). Одним из возможных результатов неопределенного поведения является получение ожидаемого результата. По какой-то причине printf
смог обработать это значение int *
как int
. Большинство компиляторов должны помечать это несоответствие типов, но вы можете поднять уровень предупреждения, чтобы увидеть это.
На двоичный оператор *
наложено ограничение, согласно которому оба операнда имеют арифметический тип. int *
не является арифметическим типом, отсюда и диагностика.
Основываясь на том, как вы на самом деле используете amount
в своем коде, вы должны были объявить его не как указатель, а как обычный int
:
int amount = 9;
Во-вторых, как правило, вы не хотите присваивать исходному указателю результат realloc
. Если realloc
не удастся, он вернет NULL
и оставит исходный блок памяти как есть. Однако, если вы вернете этот NULL
исходному указателю, вы потеряете доступ к этой памяти. Лучше всего присвоить результат realloc
временному объекту, а затем убедиться, что временный объект действителен, прежде чем назначать его обратно оригиналу:
int *tmp = realloc( array, amount * sizeof *array );
if ( tmp )
{
array = tmp;
}
else
{
// handle realloc error
}
Обратите внимание на использование sizeof *array
вместо sizeof (int)
. sizeof
— это оператор, подобный унарному *
или унарному +
, и его операнд может быть либо именем типа в скобках, либо выражением. выражение *array
имеет тип int
, поэтому sizeof *array == sizeof (int)
. Это помогает сделать код немного легче для чтения, и если вы когда-нибудь измените тип array
(скажем, на double *
), вам не придется обновлять вызов realloc
. Это также очень полезно при распределении типов многомерных массивов — вы бы предпочли написать
int (*arr)[10] = malloc( sizeof (int) * 10 * rows);
or
int (*arr)[10] = malloc( sizeof *arr * rows );
?
person
John Bode
schedule
13.06.2018
int *amount = 9;
? Это означает, чтоamount
указывает на адрес9
, и, вероятно, там нет ничего полезного. Зачем делатьamount
указателем для начала? Какую проблему это должно решить? - person Some programmer dude   schedule 13.06.2018int *amount = 9;
. Вместо этого я попытался сделать это:int *amount
иamount = 9;
, и оказалось, что это одно и то же. Я предполагаю, что делаю правильно (поскольку я также помню, как мой лектор говорил мне об этом)? Кроме того, я пытаюсь передать его по ссылке позже в функцию. Есть ли другой способ сделать это? - person Richard   schedule 13.06.2018&
. Как и вint amount = 9; ...; some_function(&amount);
, используйте оператор разыменования*
для доступа к тому, на что указывает указатель внутри функции. - person Some programmer dude   schedule 13.06.2018int *amount = 9;
заставляетamount
указывать на адрес9
. Это не делаетamount
указанием на какое-то целое число, имеющее значение9
, это было бы что-то вродеint real_amount = 9; int *amount = &real_amount;
- person Some programmer dude   schedule 13.06.2018