Почему передача по ссылке работает только с указателями, объявленными в списке аргументов этой программы на C?

Это программа 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;
}

Это базовые знания. Я думаю, вам следует прочитать главу, посвященную указателям, в учебнике по C.

Jabberwocky 28.05.2019 21:46
read_data(&a, &b, c); передает в функцию адреса трех переменных, определенных в main. Они указатели. Третий c — это массив, который распадается на нужный указатель. Обратите внимание, что параметры функции char *char_ptr и char k[] практически одинаковы — вы не можете передать массив функции.
Weather Vane 28.05.2019 21:51
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 записывает данные. Адрес указателя не имеет значения.
William Pursell 28.05.2019 22:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это не противоречит, вы просто делаете вывод о неправильных атрибутах функции.

Обратите внимание на разницу между:

Объявление функции:

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)

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