Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
вумип.doc
Скачиваний:
4
Добавлен:
27.09.2019
Размер:
362.5 Кб
Скачать

27.Указатели

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

Формат объявления указателя: спецификатор-типа [ модификатор ] * описатель.

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

Для модификации размера указателя можно использовать ключевые слова near, far, huge.

Примеры:

unsigned int * a; /* переменная а представляет собой указатель на тип unsigned int */

char * fuffer ; /* объявляется указатель с именем fuffer который указывает на переменную типа char */

double nomer; void *addres; addres = & nomer; (double *)addres ++;

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

const * dr;

/Переменная dr объявлена как указатель на константное выражение, т.е. значение указателя может изменяться в процессе выполнения программы, а величина, на которую он указывает, нет.

unsigned char * const w = &obj.

Переменная w объявлена как константный указатель на данные типа char unsigned. Это означает, что на протяжение всей программы w будет указывать на одну и ту же область памяти. Содержание же этой области может быть изменено.

Операции разадресации и адреса

Операция разадресации (*) исп-ся для нахождения данных по исвестному адресу. Результатом операции является величина, на которую указывает указатель. Типом результата является тип величины, адресуемой указателем. Результат не определен, если указатель содержит недопустимый адрес (указатель является нулевым или указатель определяет адрес такого объекта, который не является активным в момент ссылки).

Операция взятия адреса (&) исп-ся для определения адреса переменной, содержащей данные. Тип, адресуемый указателем, является типом операнда.

Операция адрес не может применятся к элементам структуры, являющимися полями битов, и к объектам с классом памяти register.

Примеры:

int t, f=0, * adress;

adress = &t; /* переменной adress, объявляемой как указатель, присваивается адрес переменной t */

* adress =f; /* переменной находящейся по адресу, содержащемуся в переменной adress, присваивается значение

переменной f, т.е. 0 , что эквивалентно t=f; т.е. t=0; */

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

[спецификатор-класса-памяти] [спецификатор-типа] имя-функции ([список-формальных-параметров]){тело-функции }

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

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

Пример:

int rus (unsigned char r) { if (r>='А') return 1; else return 0; }

В данном примере определена функция с именем rus, имеющая один параметр с именем r и типом unsigned char. Функция возвращает целое значение, равное 1, если параметр функции является буквой русского алфавита, или 0 в противном случае.

Вызов ф-ии может предшествовать определению (при этом до вызова функции нужно поместить объявление (прототип) функции – определение без тела функции int min(int,int)); если объявление ф-ии не задано, то компиллятор строит автомат. прототип на основе первого вызова. Определения используемых функций могут следовать за определением функции main, перед ним, или находится в другом файле.

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

1. Функция возвращает значение типа, отличного от int.

2. Требуется проинициализировать некоторый указатель на функцию до того, как эта функция будет определена.

int rus (unsigned char r); или rus (unsigned char);

Вызов функции – указание в тексте имени функции со списком фактических параметров.

Вызов функции имеет следующий формат: адресное-выражение ([список-выражений])

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

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

Выполнение вызова функции происходит следующим образом:

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

2. Происходит присваивание значений фактических параметров соответствующим формальным параметрам.

3. Управление передается на первый оператор функции.

4. Выполнение оператора return в теле функции возвращает управление и возможно, значение в вызывающую функцию. При отсутствии оператора return управление возвращается после выполнения последнего оператора тела функции, а возвращаемое значение не определено. Пример int min(int a, int b);

min(int, int); /*вызов ф-ии min*/

37.Фактические и формальные параметры

Формальные параметры- пар-ры, перечисленные в заголовке описания ф-ии.

Фактические параметры(аргументы)- записанные в операторе вызова функции.

Список-формальных-параметров — это последовательность объявлений формальных параметров, разделенная запятыми.

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

Способы передачи параметров в функцию:

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

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

14. Структура программы на языке с

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

Эти инструкции имеют вид

Include < имя заголовочного файла>

Все заголовочные файлы имеют расширение h. Как правило, в программе присутствуют по крайней мере две инструкции:

Include <stdio.h> Include <conio.h>

первая из которых обеспечивает подключение функций ввода-вывода при работе с экраном и файлами, а вторая — функции управления работой монитора (очистка экрана, перемещение кур­сора, определение цветов фона и символов и т.п.). Кроме того, часто используются инструкции

Include <math.h> Include <string.h> Include<dir.h> Include <dos.h>

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

Каждая инструкция include записывается с новой строки. В кон­це инструкции никакие разделительные знаки не используются.

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

void main ()

за которым никакие знаки препинания не ставятся.

За заголовком следует тело этой функции — последователь­ность выполняемых операторов, заключенная в фигурные скоб­ки, которые имеют смысл аналогичный begin и end в языке Pascal. Каждый оператор обязательно должен завершаться символом «;» (точка с запятой). Обычно каждый из операторов записывается с новой строки, что обеспечивает хороший обзор программы.

Если программа содержит несколько функций, то они распо­лагаются последовательно одна за другой, причем функция main может занимать в этой последовательности произвольное место. Выполнение программы в любом случае начинается с выполне­ния функции main

#include <stdio.h>

#include <conio.h>

void mainO

{

printf("Унылая пора! Очей очарованье!\n");

printf("Приятна мне твоя прощальная краса -\п");

printf("Люблю я пышное природы увяданье,\п");

printf("В багрец и золото одетые леса.\п\п");

printf(" А.С.Пушкин\п");

printf("\п\пДля завершения нажмите <Enter>");

getchО; // чтобы стихотворение не исчезло с экрана

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]