Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования на языке C_4.docx
Скачиваний:
47
Добавлен:
25.03.2016
Размер:
300 Кб
Скачать
☆

Локальные переменные

Переменные, известные только одной функции, а именно той, которая их содержит, называются локальными переменными. Теперь мы подчеркиваем, что локальные переменные являются действительно локальными. Даже в том случае, когда мы используем одно и то же имя для переменных в двух различных функциях, компилятор считает их разными переменными.

Нахождение адресов

В результате выполнения операции & определяется адрес ячейки памяти, которая соответствует переменной. Если age - имя переменной, то &age - ее адрес. Можно представить себе адрес как ячейку памяти, но можно рассматривать его и как метку, которая используется компилятором для идентификации переменной. Предположим, мы имеем оператор

age=105;

Пусть также адрес ячейки, где размещается переменная age - 15125. В результате выполнения оператора

printf("%d %d\n", age, &age);

получим 105 15125.

Указатели, первое знакомство

Указатель - некоторое символическое представление адреса. В описанном примере &age означает указатель на переменную age. Фактический адрес - это число, а символическое представление адреса &age является константой типа указатель. Адрес ячейки, отводимой переменной age, в процессе выполнения программы не меняется. В языке Си имеются и переменные типа указатель. Точно так же как значением переменной типа char является символ, а значением переменной типа int - целое число, значением переменной типа указатель служит адрес некоторой величины. Если мы дадим указателю имя ptr, то сможем написать, например, такой оператор:

ptr = &age;

/* присваивает адрес age переменной ptr */

Мы говорим в этом случае, что ptr указывает на age. Различие между двумя формами записи, ptr и &age, заключается в том, что ptr - это переменная, в то время как &age - константа. В случае необходимости мы можем сделать так, чтобы переменная ptr указывала на какой-нибудь другой объект:

ptr = &name;

/*ptr указывает на name, а не на age*/

Теперь значением переменной ptr является адрес переменной name.

Операция косвенной адресации *

Предположим, мы знаем, что в переменной ptr содержится ссылка на переменную name. Тогда для доступа к значению этой переменной можно воспользоваться операцией косвенной адресации *:

val = *ptr;

/* определение значения, на которое указывает ptr */

Последние два оператора, взятые вместе, эквивалентны следующему:

val = name;

Описание указателей

Примеры описания указателей:

int *pi; /*указатель на переменную типа целого*/

char *pc; /*указатель на символьную переменную*/

float *pf, *pg;

/* указатели на переменные с плавающей точкой*/

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

При вызове функции информация о переменной может передаваться функции в двух видах. Если мы используем форму обращения

function1(x);

происходит передача значения переменной x. Если же мы используем форму обращения

function2(&x);

происходит передача адреса переменной x. Первая форма обращения требует, чтобы определение функции включило в себя формальный аргумент того же типа, что и x:

function1(num)

int num;

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

function2(&ptr)

int *ptr;

!

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