Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие С(часть1-3).doc
Скачиваний:
23
Добавлен:
12.02.2015
Размер:
854.02 Кб
Скачать

Int *t; // неинициализированный указатель на объект типа int,

//то есть в переменной T может храниться адрес объекта типа int;

В качестве инициализирующего выражения указателя может использоваться константное выражение, частными случаями которого являются явно заданный адрес участка памяти, указатель, уже имеющий значение, выражение, позволяющее получить адрес объекта с помощью операции ‘&’. Например,

char c1 = ‘a’;

char* p = &c1;// в p хранится адрес переменной c1

Переменная, на которую указывает p, это c1, а значение, которое хранится в c1, это символ ‘a’. Основная операция над указателем – разыменование, унарная операция ‘*’ (получение значения через указатель). Эта операция также называется косвенным обращением или обращением по адресу. Например, при выполнении оператора printf(“%c”, *p); на экран выведется значение того участка памяти, с которым связан указатель p, то есть символ ‘a’.

Имя массива является указателем–константой на его первый элемент. То есть, если описан массив int a [n], то для обращения к его i–ому элементу наряду с записью a[i], можно использовать запись *(a+i).

Например, пусть описан и инициализирован массив a.

const int n=5;

int a[n]={1,2,3,4,5};

Выведем его элементы на экран столбиком тремя способами:

  1. int *p=a; for (int i=0;i<n;i++ ) printf("%d%s",*p++, "\n");

  2. for (int i=0;i<n;i++ ) printf("%d%s",*(a+i), "\n");

  3. for (int i=0;i<n;i++ ) printf("%d%s", a[i], "\n");

Чтобы связать указатель с новым участком памяти, еще не занятым никаким объектом программы, используют функцию malloc (n) из библиотеки stdlib.h, где n – количество выделяемых байт. Функция malloc возвращает укатель на void, потому при присваивании ее результат необходимо преобразовать в указатель на нужный тип данных. Например,

char *p= (char*)malloc(sizeof(char)); //выделили память для перемененной типа

// char и связали указатель p с эти участком памяти;

Объекты, созданные таким образом (динамические объекты), требуют явного уничтожения с помощью функции free(t) из библиотеки stdlib.h (), где t- имя указателя из-под которого осбождается память, например

free(p);

Функция malloc позволяет определять массив еще одним способом:

int k;

scanf(“%d”,&k);

int *a=(int *)malloc(k*sizeof(int));

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

Специальным образом в языке С обрабатываются массивы, называемые С–строками. С–строка – это массив символов, последний из которых символ ‘\0’. Дело в том, что в С нет специального типа данных для описания строк, но есть библиотека функций языка С для работы С–строками (описанная в заголовочном файле string.h, см.задание 15),которые обеспечивают различные операции для манипулирования строками. В этой главе мы рассмотрим работу, используя обычный принцип обработки символов как элементов массива.

При инициализации массив символов можетзадаваться как последовательность символов, заключенная в двойные кавычки: “...”. Компилятор располагает в конце каждой строки нулевой (пустой) байт, обозначемыesc-последовательностью ‘\0’, с тем, чтобы сканирующая строку программа могла найти ее конец. Например,

char str1[]= “abcd”; // действительная длина этой строки равна 5

char * str2= “abcd”; // действительная длина этой строки равна 5

Кроме того, инициализация строк может быть выполнена следующим образом:

char str3[]={‘a’, ‘b’, ‘c’, ‘d’, ‘\0’};

При такой инициализации списком, а также при посимвольном заполнении неинициализированного массива в цикле в конце символьного массива следует явным образом задать символ конца строки ‘\0’. Только при этом массив получает свойства С–строки, которые можно использовать, например, в библиотечных функциях для работы со строками или при вводе и выводе строки. Например, С–строку str3 в отличии от любого несимвольного массива можно вывести на экран не в цикле, а с помощью с помощью одного оператораprintf(“%s”,str2). А неинициализированный массивcharstr4[20], в отличии от любого несимвольного можно заполнить одним операторомscanf(“%s”, str3); Однако, как отмечено в главе 2, при применении функцииscanfклавиатуры считаются в массив str3 все символы только до первого пробела. Чтобы считать строку целиком, можно использовать функцию

gets (указатель_на_строку),

описанную в заголовочном файле stdio.h. Например,

char s1[10]; gets(s1);

char * s2 = (char *)malloc(m); scanf(“%s”, str3);

Строка s1 – это массив с константой размерностью 10, элементы которого считываются с клавиатуры с помощью функции gets. Строка s2 – это динамический массив из m элементов, в который считается только m–4 символов (m–3–ий элемент будет равен ‘\0’). Причем второй способ считывания строки предпочтительнее, чем первый, так как функция gets не накладывает ограничения на число считываемых с клавиатуры символов, а это значит, что массив s1 может переполниться.

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

# include <stdio.h>