2012-03-12 4 views
0

Я новичок в Linux. Я наткнулся на эту часть кода, чтобы напечатать переменные среды. Меня это пугает. Как этот код может печатать переменные среды?Печать переменных окружения в Linux

#include <stdio.h> 

extern char **environ; 
int main() 
{ 
    char **var; 
    for(var=environ; *var!=NULL;++var) 
     printf("%s\n",*var); 

    return 0; 
} 

Что такое extern?

ответ

1

Если вы не знаете, что extern означает, что вы найдете книгу, в которой можно узнать C. Это просто означает «определено где-то еще, но используется здесь».

В настоящее время глобальная переменная <unistd.h> объявлена ​​(хотя долгое время не было заголовка, объявившего ее). Это похоже на массив argv для программы, массив указателей символов, каждый из которых указывает на переменную среды в формате name=value. Список завершается нулевым указателем, например argv. Тем не менее, нет никакого количества для окружающей среды.

for (var = environ; *var != NULL; ++var) 
    printf("%s\n", *var); 

Таким образом, на первой итерации, var точки на первой переменной окружения; то он увеличивается до следующего, пока значение *var (a char *) не равно NULL, что указывает на конец списка.

Этот цикл также может быть записана в виде:

char **var = environ; 
while (*var != 0) 
    puts(*var++); 
+0

Почему мы использовали ++ var? cant мы используем ++ var – user1263375

+0

В коде цикла 'for',' ++ var' и 'var ++' по существу одинаковы. В коде цикла while, используя '* ++ var', пропустит первую запись. Есть связанная программа, которую я называю 'al' (для списка аргументов), которая похожа на' echo', но печатает свои аргументы по одной в строке: '#include int main (int argc, char ** argv) {while (* ++ argv) puts (* argv); return 0; } ', который использует' * ++ argv' вместо аналогичного '* var ++', потому что он намеренно пропускает имя программы. –

1

Из википедии http://en.wikipedia.org/wiki/External_variable:

Определение, декларации и экстерном ключевое слово

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

Ключевое слово extern означает «объявить без определения». Другими словами, это способ явно объявить переменную или принудительно объявить без определения. Также можно явно определить переменную, т. Е. Принудительное определение. Это делается путем присвоения переменной значения инициализации. Если ни ключевое слово extern, ни значение инициализации не присутствуют, оператор может быть объявлением или определением. Компилятор должен проанализировать модули программы и решить.

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

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

Ключевое слово extern, примененное к прототипу функции, абсолютно ничего (ключевое слово extern, примененное к определению функции, конечно, не является ощутимым). Прототип функции всегда является декларацией и никогда не является определением. Кроме того, в ANSI C функция всегда является внешней, но некоторые расширения компилятора и более новые стандарты C позволяют определять функцию внутри функции.

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

-The Язык программирования C

Scope, время жизни и статическое ключевое слово

Внешняя переменная может быть доступна всем функциям во всех модулях программы. Это глобальная переменная. Чтобы функция могла использовать переменную, декларация или определение внешней переменной должны лежать перед определением функции в исходном коде. Или должно быть объявление переменной с ключевым словом extern внутри функции.

Статическое ключевое слово (static и extern взаимоисключающее), применяемое к определению внешней переменной, немного изменяет это значение: к переменной могут обращаться только функции в том же модуле, где она была определена. Но функция в том же модуле может передать ссылку (указатель) переменной на другую функцию в другом модуле. В этом случае, хотя функция находится в другом модуле, она может читать и изменять содержимое переменной - она ​​просто не может ссылаться на нее по имени.

Также можно использовать статическое ключевое слово в определении локальной переменной. Без ключевого слова static переменная автоматически выделяется, когда функция вызывается и освобождается при выходе из функции (таким образом, это имя «автоматическая переменная»). Его значение не сохраняется между вызовами функций. С ключевым словом static эта переменная выделяется, когда программа запускается и отпускается, когда программа заканчивается. Его значение не теряется между вызовами функций. Эта переменная по-прежнему является локальной, поскольку ее можно получить только по имени внутри функции, которая ее определила. Но ссылку (указатель) на нее можно передать другой функции, позволяя ей читать и изменять содержимое переменной (опять же без ссылки на нее по имени).

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

Если инициализация не выполняется явно, внешние (статические или нет) и локальные статические переменные инициализируются до нуля. Локальные автоматические переменные не инициализируются, т. Е. Содержат значения «мусор».

Статическое ключевое слово, применяемое к определению функции, не позволяет функции вызываться по имени из-за пределов ее модуля (остается возможность передать указатель функции из модуля и использовать это для вызова функции).

Пример (C язык программирования)

Файл 1:

int GlobalVariable;   // implicit definition 
    void SomeFunction();  // function prototype (declaration) 

    int main() { 
    GlobalVariable = 1; 
    SomeFunction(); 
    return 0; 
    } 

Файл 2:

extern int GlobalVariable; // explicit declaration 

    void SomeFunction() {  // function header (definition) 
    ++GlobalVariable; 
    } 

В этом примере переменная GlobalVariable определен в файле 1. Для того, чтобы используйте ту же переменную в файле 2, она должна быть объявлена. Независимо от количества файлов глобальная переменная определяется только один раз, однако она должна быть объявлена ​​в любом файле за пределами того, который содержит определение.

Если программа находится в нескольких исходных файлах, а переменная определена в файле1 и используется в файлах2 и файле3, в файлах2 и file3 требуются объявления extern для подключения вхождения переменной. Обычной практикой является сбор extern-деклараций переменных и функций в отдельном файле, исторически называемом заголовком, который включен #include в начале каждого исходного файла. Суффикс .h является обычным для имен заголовков.

0

внешний символ ** окружающая среда;

переменная environ исходит из вашей библиотеки, которую вы связываете.

Эта переменная сохраняются системные переменные окружения вашей текущей

системы Linux. Вот почему вы можете это сделать.

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