Ссылки на С - PullRequest
       13

Ссылки на С

0 голосов
/ 17 августа 2011

Это теоретический вопрос.

Интересно, как некоторые конструкции в C выполняются внутри без ссылок.Например:

struct Foo { int a; };
int main() {
  struct Foo foo;
  foo.a = 10;
  return 0;
}

Какой тип foo.a?Это определенно не указатель, потому что мы присваиваем 10 в качестве значения, а не адреса.Но это также не тип значения, потому что он изменяет данные foo.В C ++ я бы просто сказал, что это ссылка, а в C?

Ответы [ 4 ]

7 голосов
/ 17 августа 2011

Это int lvalue.То же самое, как если бы у вас было int bar, а bar = 10 изменяет данные bar.То же самое относится к любому элементу в массиве.По сути, все, что вы можете получить по адресу, является lvalue.

Статус Lvalue не зависит от типа.

1 голос
/ 17 августа 2011

Тип foo.a равен int.Подумайте об этом так: запись foo.a = 5 - это то же самое, что запись *((int*)(&foo + offset_of_a)) = 5 - это просто запись данных в определенную область памяти, которая должна интерпретироваться как значение типа int.

1 голос
/ 17 августа 2011

Единственная причина, по которой ссылка здесь "нужна" в C ++, - перегрузка операторов. В C знак = не является вызовом функции, который нуждается в ссылочном аргументе. Это просто оператор. Он не может быть переопределен и создан для бессмысленных вещей, поэтому для него вполне подходит нормальное lvalue.

Обратите внимание, что для этой цели C ++ также не нужны ссылки. С тем же успехом можно было бы указать перегруженные функции operator= и т. Д. Для получения указателей, а не ссылок.

0 голосов
/ 17 августа 2011

Структуры в c на самом деле просто большие примитивы. если вы посмотрите на ассемблер, сгенерированный для вашего назначения foo, он просто действует как int. Вот пример:

У меня есть определение структуры:

 typedef struct Foo Foo;
 struct Foo {
     int a, b;
 };

И я объявляю Foo:

 Foo foo = {0,1};

Стек (некоторые мелочи, относящиеся к конкретной машине, затенены, но в целом) выглядит следующим образом (при условии 4-битных целых и однобитных байтов)

%esp  %ebp[-8]  %ebp[-4]  %ebp
[....   0000      0001    ....]

вы обнаружите, что инструкция для назначения foo.b = 1 равна

mov $1, -4(%ebp)

Это та же самая инструкция, которая присваивает int в стеке значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...