2014-12-05 2 views
0

Источник:отображение памяти для статических переменных

func_1() 
{ 
    static int i = 10; 
    printf("%s : %d\n", __func__, i); 
} 

func_2() 
{ 
    static int i = 20; 
    printf("%s : %d\n", __func__, i); 
} 

main() { 
    static int i = 30; 
    func_1(); 
    func_2(); 
    printf("%s : %d\n", __func__, i); 
} 

Выход:

func_1 : 10 
func_2 : 20 
main : 30 

Как компилятор дифференцироваться переменные в сегменте данных по функциям?

+0

Непонятно, что вы просите. Вы спрашиваете, как компилятор знает, в какой области он находится? –

+0

* Как * обработчик компилятора не указан, это зависит от компилятора. До тех пор, пока он ведет себя так, как указано, действительно ли это имеет значение? –

+0

@DavidSchwartz да. также, как извлекается фактическое значение. – codedoc

ответ

2

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

0

Это полностью связано с областью действия переменной. Здесь три i s представляют собой три отдельные переменные, каждая из которых имеет свою собственную область действия, в той конкретной функции, которую она определена.

func_1 : 10 является правильным, поскольку, i является местным для func_1() здесь.

func_1() 
{ 
    static int i = 10; 
    printf("%s : %d\n", __func__, i); 
} 

func_2 : 20 тоже правильно, потому что, i является локальным для func_2() здесь.

func_2() 
{ 
    static int i = 20; 
    printf("%s : %d\n", __func__, i); 
} 

main : 30 тоже правильно, потому что, i является локальным для main() там.

Side Примечание:

  1. Если вы думаете, из-за static модификатора, все переменный будет ступать как одно, то ты не впал в множественное определение ошибки? :-)
  2. В случае local и переменной global с таким же именем функция local будет отдана предпочтение функции.
0

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

0

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

Так что если вы немного измените свой код, чтобы напечатать адрес i, вы увидите, что у каждого i есть другой адрес.

func_1() 
{ 
    static int i = 10; 
    printf("%s : %d, %p\n", __func__, i, &i); 
} 

func_2() 
{ 
    static int i = 20; 
    printf("%s : %d, %p\n", __func__, i, &i); 
} 

main() { 
    static int i = 30; 
    func_1(); 
    func_2(); 
    printf("%s : %d, %p\n", __func__, i, &i); 
} 

Пример вывода

func_1 : 10, 0x601028 
func_2 : 20, 0x601024 
main : 30, 0x601020 
1

Существует, вероятно, больше, чем один способ компилятор справиться с этим, но вот один вариант:

  • Обобщение функций по одному
  • Всякий раз, когда вы сталкиваетесь с объявлением статической переменной, выделите новую запись в разделе данных
  • Всякий раз, когда вы сталкиваетесь статическую ссылку на переменную, замените его на адрес новой записи

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

Конечно, с нестатистическими локальными переменными полный перевод адреса будет происходить только во время выполнения.

Но понятие одно и то же - как только функция скомпилирована, имена ее переменных бессмысленны.

Смежные вопросы