Как эта C-программа компилируется и запускается успешно? - PullRequest
3 голосов
/ 13 июля 2011

Меня спросили об этом в интервью.Каким будет результат этой программы?Я уверенно сказал, что это не будет компилироваться.Я сказал, что a является именем массива и не занимает места, поэтому & a не должно иметь никакого смысла, поэтому это не скомпилируется.но на практике получается, что он компилируется и работает успешно.Может кто-нибудь объяснить, как это работает.

main()    
{
    int a[50];
    &a; // or perhaps the interviewer wanted to know the output of this line..
}

Ответы [ 5 ]

4 голосов
/ 13 июля 2011

Строка &a; просто вычисляет адрес массива a и молча отбрасывает его.

3 голосов
/ 13 июля 2011

интервьюер явно должен получить новый тестовый материал :) Это…

main()    
{
    int a[50];
    &a;
}

… является старым K & R C. Если не объявлено иначе, функция возвращает int, и последний оператор функции возвращается неявно. Вы можете переписать это в ANSI C следующим образом:

int main()    
{
    int a[50];
    return &a;
}

Итак, давайте рассмотрим эту программу:


int main()    

Определить функцию main, возвращающую int, принимающую произвольные параметры.


{
    int a[50];

Определите массив из 50 int в автоматическом хранилище и присвойте указатель int (int*) на первый элемент этого массива переменной литерала a.


    return (intptr_t)&a;
}

Теперь это немного сложно. Просто запись a приводит к адресу первого элемента массива . Оператор & принимает адрес переменной , в которой хранится этот конкретный указатель. Неважно, что где-то выделено 50 int, и эта переменная в данный момент указывает на него. Мы берем указатель на указатель, то есть указатель int (int**). массив, снова его первый элемент.

Однако K & R C определяет неявное преобразование типов указателей в целые числа. Значение этого указателя однозначно идентифицирует исходный указатель и должно соответствовать арифметике указателя. Большинство компиляторов реализуют это, просто сохраняя дословный адрес указателя в целом числе. Важное исключение: любое специальное машинно-зависимое значение nil-указателя должно отображаться в 0 на стороне C, а int или intptr_t из 0 приведения к указателю должно соответствовать значению nil архитектуры (на большинстве архитектур значение nil компьютера равно 0 тоже).

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


Компиляция этой программы

cc -o interview_question interview_question.c

Вы можете выполнить и отобразить код выхода, используя

./interview_question ; echo $?

Это будет произвольное, но не случайное число.

РЕДАКТИРОВАТЬ в связи с комментариями и исправлениями @John Bodes.

3 голосов
/ 13 июля 2011

Эта программа не имеет видимого результата. Он успешно скомпилирован, но не имеет наблюдаемого поведения.

&a является выражением. Поскольку a является объектом типа массива, &a является адресом массива (его значение может совпадать с &a[0], но его тип не совпадает - int* против int(*)[50]). Любое выражение, за которым следует точка с запятой, является выражением выражения. Тело функции - это последовательность из нуля или более операторов, заключенная в {}. Следовательно, это допустимая функция main(). (Когда вы пишете a[0] = 10;, это тоже выражение выражения.)

В соответствии с правилом «как будто» стандарта C ++ реализация может даже решить не выделять какую-либо память для вашего массива и вообще ничего не делать, потому что даже если бы это было так, у вас не было бы никакого способа проверить это (по крайней мере, с точки зрения C ++).

Это также допустимая программа на C ++

int main()
{
   1; 2; 3;
}
2 голосов
/ 13 июля 2011

Вы можете использовать выражение как утверждение, оно совершенно верно.Это ничего не сделает.

1 голос
/ 13 июля 2011

Этот код должен скомпилироваться и работать успешно, как я чувствую.a - это массив, & a - это не что иное, как адрес первого индекса (такой же, как a).so & a - это выражение, которое ничего не делает ... оно так же, как:

int x;& x;

Вывод этого не будет, так как выражение 2 ничего не делает.

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