Вот что-то я не понимаю. Может быть, кто-то может пролить свет на это.
Я знаю, что стандартный метод манипулирования данными — это передача ссылки на функцию и изменение данных в функции. Как это:
#include <stdio.h>
#include <stdlib.h>
void function2( float *param) {
printf("I've received value %f\n", *param);
(*param)++;
}
int main(void) {
float variable = 111;
function2(&variable);
printf("variable %f\n", variable);
return 0;
}
При вызове function2 с (&variable) я ожидаю, что функция может изменить данные. Пока без вопросов.
Но почему это тоже работает?
#include <stdio.h>
#include <stdlib.h>
void function2( float ¶m) {
printf("I've received value %f\n", param);
(param)++;
}
int main(void) {
float variable = 111;
function2(variable);
printf("variable %f\n", variable);
return 0;
}
Насколько я понимаю, при вызове функции2(переменной) в функцию передается копия значения "переменной". Но тем не менее значение "переменной" изменилось после вызова функции.
При чтении такого кода я бы никогда не ожидал, что данные «переменной» изменятся, независимо от того, что происходит внутри функции.
Вы можете добавить #ifdef __cplusplus
/ #error wrong (or mis-configured) compiler
/ #endif
к своим исходным файлам :-)
Как вы думаете, что делает &
?
Вариант 1 ожидает указатель в качестве аргумента. Следовательно, вам нужно явно передать &variable
.
Вариант 2 ожидает Справка в качестве аргумента. Они как бы похожи на указатель в том смысле, что они по-прежнему указывают на исходное место в памяти, но также немного отличаются тем, что с точки зрения типа они немного больше, чем просто адрес в памяти. Например, если я правильно помню, вы не можете делать фанковые арифметические операции с указателями со ссылкой.
Как видите, если функция ожидает ссылку в качестве аргумента, компилятор будет знать, что делать, и вам не придется явно создавать ссылку.
Кроме того, как вы можете видеть, это может привести к неприятным сюрпризам, если кто-то вызовет вашу функцию и не ожидает, что она изменит исходные данные. Вот почему в чистом коде не появляются неожиданные побочные эффекты; если функция путается с входными данными, это должно быть единственное, что она делает, и это должно быть совершенно явным.
Чтобы наконец получить вариант, который нет изменяет оригинал, выполните
void function2( float param)
в объявлении функции. Нет *
и нет &
. В этом случае функция не получает указатель или ссылку, а просто значение с плавающей запятой, которое теперь будет копировать входного аргумента и, следовательно, не изменит вашу переменную.
Это С, а не С++. См. replit.com/@robertwharvey/…
Скорее всего, OP просто использовал C и C++ взаимозаменяемо?
Это объявление параметра
void function2( float ¶m) {
это неверно. В C нет ссылки. Такое объявление функции будет допустимо в C++, где существуют ссылки.
В С++, когда функция вызывается как
function2(variable);
ни одна копия переменной не создается. Функция ссылается на исходную переменную, объявленную в main.
Размещенный вами код не компилируется компилятором C, поскольку он не является допустимым кодом C. В C нет ссылочных типов данных, в отличие от C++. Имя переменной или параметра не может начинаться с амперсанда. Пожалуйста, используйте компилятор C, если вы хотите писать на C. Наиболее популярным будет компилятор GNU C (GCC) https://gcc.gnu.org/, а более легкой альтернативой будет TinyCC, оба доступны в репозиториях большинства распространенных дистрибутивов.
Вы также должны указать компилятор, операционную систему и (если применимо) IDE, которые вы используете в своих будущих вопросах.
В вашем первом примере кода используется указатель на (т.е. адрес) параметра. Вы называете это «ссылкой», что теоретически правильно. Но поскольку в C++ ссылка — это нечто другое (см. ниже), использование этого термина для указателя довольно редко.
В вашем втором примере кода используется ссылка. Но это не C. Ссылки — это функция C++. Это означает, что используемый вами компилятор принимает это (и, вероятно, является компилятором C++).
C++ — это надмножество C, поэтому программа может выглядеть как C, но использовать функции C++.
Размещенный вами код не компилируется компилятором C, поскольку он не является допустимым кодом C. В C нет ссылочных типов данных, в отличие от C++. Имя переменной или параметра не может начинаться с амперсанда. Пожалуйста, используйте компилятор C, если вы хотите писать на C.
Не уверен, почему это работает для вас. См. replit.com/@robertwharvey/…