Таким образом, у меня было это упражнение в моем классе, где я должен был сказать, какой из двух адресов больше, когда я создал два символа в основной функции.
Поскольку локальные переменные хранятся в стеке, который начинается с высокого адреса и снижается до низкого адреса. Ответ был прост: первый символ имеет больший адрес.
Но потом я написал небольшую тестовую программу:
#include "stdio.h"
int main(void)
{
int a = 3;
int b = 4;
printf("Size a: %lu \n"
"size b: %lu \n",
sizeof(a),
sizeof(b));
printf("Address a: %p \n"
"Address b: %p \n",
(void *)&a,
(void *)&b);
return 0;
}
Вывод:
Size a: 4
size b: 4
Address a: 0x7fffa1eb8a98
Address b: 0x7fffa1eb8a9c
Вывод вводил в заблуждение, адрес второго символа был больше. Я попробовал то же самое на компьютере в моем университете, и все было хорошо. Знаете, почему это так?
Я на Ubuntu 13.04 64bit.
Стандарт С, как он определен Kernighan & amp; Ричи в своей книге «Язык программирования Си» не определяет, как параметры передаются в функции, а также не определяет, как хранятся локальные переменные, что определяет реализацию.
Документация к вашему компилятору должна содержать информацию о том, как передаются параметры, потому что в противном случае вы не сможете написать ассемблерный код для связи с ним. Для локальных переменных ограничений еще меньше, так как они будут доступны только из функции, поэтому компилятор может решить вообще не хранить переменную в памяти, если он может сохранить ее в регистре. Когда вы спросили адрес переменной, компилятор был вынужден сохранить его в памяти, но если вы не используете указатель на конкретную переменную, это не требуется.
Два разных компилятора могут работать по-разному. Многие компиляторы предпочитают использовать стек, но другие вместо этого будут использовать регистры там, где это возможно, и даже там, где они используют стек, порядок параметров зависит от реализации.
Стандарт ANSI C как таковой не изменился.
Короче говоря, Ubuntu не хранит переменные в неправильном порядке. Компилятор, который вы используете в Ubuntu, просто сохраняет их в другом порядке, чем тот, который вы используете в университете. Ни один не так. Они просто разные, и документация компилятора должна объяснить, как это реализовано.
Для gcc, который большинство людей использует в Linux, документация здесь здесь .
Не думаю, что понимаю причину проблемы, но думаю, что GCC может иметь к этому какое-то отношение ... Вот сравнение между GCC и Clang.
$ gcc -o test.gcc test.c
$ ./test.gcc
Size a: 4
size b: 4
Address a: 0x7fffeef71488
Address b: 0x7fffeef7148c
$ clang++ -o test.clang test.c
$ ./test.clang
Size a: 4
size b: 4
Address a: 0x7fff664573f8
Address b: 0x7fff664573f4
Компилятор и его версия, которую вы используете в uni, могут быть здесь переменным элементом.