Это программа 3.7 из книги Роберта Вуда "Программирование на C для ученых и инженеров". В приведенном ниже коде указатели объявляются и инициализируются не в теле функции main(), а непосредственно в списке аргументов функции read_data().
Обычно при написании кода я сначала объявляю 3 указателя (int *int_ptr, float *float_ptr, char *char_ptr), а затем присваиваю им адреса a, b и c. Но в приведенной ниже программе операторы «адреса» передаются при вызове read_data(&a, &b, c); через список аргументов void read_data(int *int_ptr, float *float_ptr, char *char_ptr){...}, где у нас есть «содержимое» операторов, что кажется противоречивым, но работает. Кроме того, fscanf(stdin,"%d %f %s", int_ptr, float_ptr, char_ptr); хранит данные, предоставленные пользователем, в адресе указателей, тогда как я думаю, что они должны быть записаны в содержимом переменных a, b и c следующим образом:
fscanf(stdin,"%d %f %s", int_*ptr, *float_ptr, *char_ptr);
Но я ошибаюсь.
В противном случае программа работает, но если бы мне пришлось написать ее так, я бы не смог. Итак, я хочу, чтобы вы помогли мне понять и, возможно, предложили альтернативное решение.
/* Program 3.7- Use of functions for input and output of data */
#include <stdio.h>
int main(void) {
int a;
float b;
char c[11];
/* function prototype */
void read_data(int *, float *, char *);
void write_data(int, float, char[]);
/*call the function*/
read_data(&a, &b, c);
write_data(a, b, c);
return (0);
}
/*Function: read_data - reads an int, float and char string*/
void read_data(int *int_ptr, float *float_ptr, char *char_ptr) {
fprintf(stdout, " Supply an integer, a float and a string (max. 10 chars):");
fscanf(stdin, "%d %f %s", int_ptr, float_ptr, char_ptr);
return;
}
/* Function: write_data - displays an int, float and char string*/
void write_data(int i, float j, char k[]) {
fprintf(stdout, " The supplied data is: %d %f %s\n", i, j, k);
return;
}
read_data(&a, &b, c);
передает в функцию адреса трех переменных, определенных в main
. Они указатели. Третий c
— это массив, который распадается на нужный указатель. Обратите внимание, что параметры функции char *char_ptr
и char k[]
практически одинаковы — вы не можете передать массив функции.
fscanf(stdin,"%d %f %s", int_ptr, float_ptr, char_ptr); stores the data supplied by the user in the address of the pointers
. Нет. fscanf записывает данные в место, указанное указателями, а не по адресу указателей. Каждый указатель содержит значение, представляющее собой адрес, по которому fscanf записывает данные. Адрес указателя не имеет значения.
Это не противоречит, вы просто делаете вывод о неправильных атрибутах функции.
Обратите внимание на разницу между:
Объявление функции:
void read_data(int *int_ptr, float *float_ptr, char *char_ptr){...}
И вызов функции
read_data(int_ptr, float_ptr, char_ptr);
But in the program below, "address of" operators are passed when calling read_data(&a, &b, c); through the argument list of void read_data(int *int_ptr, float *float_ptr, char *char_ptr){...}, where we have "contents of" operators, which seems inconsistent, but works
Ваш вывод о том, что представляет собой список аргументов этой функции, вызывает ваше замешательство. Функция принимает не «содержимое» указателей, а сами указатели. А поскольку оператор «адрес» возвращает указатель, вполне нормально вызывать функцию с помощью read_data(&a, &b, c)
Это базовые знания. Я думаю, вам следует прочитать главу, посвященную указателям, в учебнике по C.