Подтвердить что ты не робот

Перейдите по ссылке в C

Я пытаюсь использовать pass by reference в C, чтобы функция могла изменять значения переданных ему параметров. Это подпись функции:

int locate(char *name, int &s, int &i)

Однако, когда я пытаюсь скомпилировать его, я получаю эту ошибку, которая относится конкретно к указанной выше строке:

error: expected ';,', or ') до '& Амп;' Маркер

Если я удалю '&' программа будет компилироваться, но она не будет функционировать корректно, очевидно. Что здесь не так? Как я могу выполнить вызов по ссылке?

4b9b3361

Ответ 1

C не имеет ссылок. Вам нужно передать указатель на переменную, которую вы хотите изменить:

int locate(char *name, int *s, int *i)
{
    /* ... */

    *s = 123;
    *i = 456;
}

int s = 0;
int i = 0;
locate("GMan", &s, &i);

/* s & i have been modified */

Ответ 2

C не имеет ссылочных переменных, но вы можете рассматривать ссылку как константный указатель на данные, поэтому

Сделайте указатель const для данных таким образом, чтобы указатель не указывал на другие данные, но данные, указываемые им, могут быть изменены.

int  locate (char *name,  int  * const s, int * const i)

Ответ 3

C не поддерживает передачу по ссылке. Вам понадобится С++, чтобы сделать это так, как он написан, или изменить на

int locate(char *name, int *s, int *i)

и передать указатели на вторую и третью переменные параметра.

Ответ 4

Вы не можете сделать это в c. c не имеет ссылки, вы можете использовать указатель вместо этого.

Ответ 5

Если вы хотите использовать метод pass by reference для изменения параметра, используемого в вызове функции, всегда используйте указатели как формальные аргументы функции.

Следовательно, вместо этого

int locate(char *name, int &s, int &i)

int locate(char *name, int *s, int *i)

Когда вы вызовете эту функцию, вы можете использовать

.........

int a=5;
int d=10;
char c='A'; 
int result;

result=locate(&c, &a, &d);

Надеюсь, теперь все будет ясно,

Для получения дополнительной информации о передаче по значению или передаче по ссылке и какой из них лучше, этот источник хорош для новичков

http://www.learnc.net/call-by-reference.php

Удачи.

Ответ 6

Более ранние ответы, по-видимому, не содержат контекста и не адресуют свойство, что перегруженные C-указатели. Совершенно справедливо утверждать, что C "проходит по ссылке". Указатель - это ссылка. Однако, более формально, C "reference" является механизмом представления адреса памяти символов.

  • Указатель - это просто переменная в памяти, значение которой рассматривается как адрес.
  • Ссылка - это просто литерал значения для адреса памяти.
  • Язык C позволяет передавать по ссылке - но только в правильном контексте!

Разделение контекста - это определение подписи и вызов сигнатуры.

Рассмотрим примитивы int a = 0x22e8;, а где-то еще мы объявим int* b = &a; (я получу функции через минуту).

Мы могли бы визуализировать это в памяти (предположим, что для этого примера не имеет значения):

...
0x00000200:        22e8        ; this is the variable for int a literal value:
                               ; a == 0x000022e8
                               ; &a == 0x00000200
0x00000???:        9090        ; ... more code ...
0x00000400:        0200        ; this is pointer b pointing to a address:
                               ; b == 0x00000200
                               ; *b == 0x000022e8
                               ; &b == 0x00000400
...

Легко видеть, что мы можем назначить указатель на любой адрес без каких-либо специальных трюков. Указатель - это просто переменная, но C позволяет нам ссылаться на адрес, на который он указывает; мы можем "разыменовать" указатель из его значения-адреса, чтобы вместо этого обработать указатель как его основное значение в контексте вызова: while ( *b == a ) .... Мы могли бы легко вызвать b == &a.

При применении этого к вызовам функций вы должны отделить контекст определения функции (подписи) против вызова, чтобы дифференцировать проход по ссылке.

int* foo(int* blah, int nah) { .. }     // signature definition context:
                                        // These are parameters
... vs ...

b = foo( &a, 4);                        // invocation context:
                                        // These are arguments

При определении сигнатуры функции мы не сообщаем компилятору, к которому обращаться с аргументом, можно получить из — время выполнения еще не известно! Это просто абсурд, чтобы определить void bar(int &blah) {...}. Вместо этого мы используем разыменованный синтаксис указателя — "любой переданный аргумент будет загружен по адресу, указанному на" — для ссылки на требуемое значение аргумента, когда выполняется время выполнения. Таким образом, C может передавать аргументы по ссылке.

Контексты как определения сигнатур функций, так и вызовов функций изменяют то, как компилятор просматривает перегрузку указателя и ссылку на него, и как среда выполнения может фактически их решить.

Ответ 7

(Я использую C некоторое время, но я все еще новичок в нескольких концепциях на C. Я стараюсь ответить на это, насколько мне известно, не стесняйтесь исправить меня, если я ошибаюсь)

Когда вы говорите, что по ссылке вы передаете адрес, и сделайте так, чтобы вы использовали указатели, указывающие на адреса. Поэтому вам нужно передать указатели на прототип функции, но то, что вы делаете, - это передать адрес напрямую.

То, что выполняет ваша функция, - это удаление ссылки (с использованием &) вашего указателя, но у вас никогда не было указателя на параметры 's' и 'i', чтобы удалить ссылку.

Правильный способ выполнения прототипа/определения функции -

int locate(char *name, int *s, int *i)

и когда вы должны вызвать эту функцию, вы используете декларацию ниже в главной или вызывающей функции

int locate(char *name, &s, &i)