Лекция: Общее знакомство
Вид материала | Лекция |
- Жизнь Клима Самгина (общее знакомство) утопия, 27.58kb.
- Лекция Общее знакомство с организмом человека Человек и окружающая среда, 81.53kb.
- Цель дисциплины, 24.29kb.
- Тема пояснения, 99.97kb.
- Общее знакомство с цветковыми растениями, 1421.63kb.
- Образовательные программы : дошкольное общее образование, начальное общее образование,, 549.09kb.
- План «курсы трейдинга» День 1 Вступительная лекция Знакомство. Базовые понятие о трейдинге., 56.64kb.
- Ю. Б. Введение в общую психологию. М., 2000. Лекция, 413.91kb.
- Урок литературы по рассказу саши черного "в лунную ночь", 85.66kb.
- Лекция со студентами асс, 33.36kb.
Локальные переменные
Переменные, известные только одной функции, а именно той, которая их содержит, называются локальными переменными. Теперь мы подчеркиваем, что локальные переменные являются действительно локальными. Даже в том случае, когда мы используем одно и то же имя для переменных в двух различных функциях, компилятор считает их разными переменными.
^
Нахождение адресов
В результате выполнения операции & определяется адрес ячейки памяти, которая соответствует переменной. Если 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;
^
Подведем итоги по указателям
Когда за знаком & следует имя переменной, результатом операции является адрес указанной переменной.
Когда за знаком * следует указатель на переменную, результатом операции является величина, помещенная в ячейку с указанным адресом.
Пример:
age = 105;
ptr =&age;/*указатель на age*/
val= *ptr;
Результатом выполнения этого фрагмента является присваивание значения 105 переменной val.
! | Пользуйтесь первой формой, если входное значение необходимо функции для некоторых вычислений или действий, и второй формой, если функция должна будет изменять значения переменных в вызывающей программе. Программисты, работающие на языке Паскаль, могут заметить, что первая форма вызова аналогична обращению с параметром-значением, а вторая-с параметром-переменной. |
Типичные определения функции имеет следующий вид:
имя (список аргументов)
описание аргументов
тело функции
Наличие списка аргументов и описаний не обязательны. Переменные, отличные от аргументов, описываются внутри тела, которое заключается в фигурные скобки.
Аргументы используются для передачи значений из вызывающей программы в функцию. Использование ключевого слова return позволяет передавать в вызывающую программу одно значение из вызываемой функции. Обычно выполнение функции не оказывает никакого влияния на значения переменных вызывающей программы. Чтобы иметь возможность непосредственно изменять значения переменных вызывающей программы, необходимо использовать указатели в качестве аргументов. Это может оказаться необходимым в случае, если в вызывающую программу требуется передать более чем одно значение.
^ Функции должны иметь тот же тип, что и значения, которые они возвращают в качестве результатов. По умолчанию предполагается, что функции имеют тип int. Если функция имеет другой тип, он должен быть указан и в вызывающей программе, и в самом определении функции.
^
Функции с переменным количеством аргументов
В языке Си допустимы функции, количество аргументов у которых при компиляции функции не фиксировано. Количество и тип аргументов становится известным только в момент вызова функции, когда явно задан список фактических аргументов (параметров). При определении и описании таких функций, имеющих списки параметров неопределенной длины. Спецификация формальных параметров заканчивается запятой и многоточием:
тип имя(спецификация-явных-параметров,...);
Здесь тип - тип возвращаемого функцией значения; имя - имя функции.
Спецификация явных параметров - список спецификации параметров, количество и типы которых фиксированы и известны в момент компиляции. Эти параметры обязательны. Каждая функция с переменным количеством параметров должна иметь хотя бы один обязательный параметр. После списка явных (обязательных) параметров ставится запятая, а затем - многоточие. Компилятор знает, что дальнейший контроль соответствия количества и типов параметров при обработке вызова функции проводить не нужно. Чтобы функция с переменным количеством параметров могла воспринимать параметры различных типов, необходимо в качестве исходных данных каким-то образом передавать ей информацию о типах параметров.
Пример:
#include
/* Функция суммирует значения своих параметров */
long summa(int m,...) /*m - число параметров*/
{
int *p=&m; /*настроили указатель на параметр m*/
long t=0;
for(;m;m--) t+=*(++p);
return t;
}
void main()
{
printf("\n summa(20,60,40)=%d",summa(20,60,40));
printf("\n
summa(10,101,102,103,104,105,106,107)=%d",
summa(10,101,102,103,104,105,106,107));
}
10. Лекция: Классы памяти и разработка программ