- •Рецензенты:
- •Лекция 1 Основные понятия языка с
- •Первая программа
- •Переменные языка с
- •Имя переменной
- •Объявление константы
- •Операции языка с
- •Лекция 2 Операторы языка с Условный оператор
- •Оператор switch
- •Циклы Цикл for
- •Циклы while и do-while
- •Оператор безусловного перехода
- •Использование операторов break, continue и goto в циклах
- •Операция условие ?
- •Лекция 3 Массивы
- •Инициализация массивов
- •Массивы символов. Строки
- •Функции для работы со строками
- •Лекция 4 Указатели
- •Объявление указателей
- •Операции над указателями
- •Связь указателей и массивов
- •Массивы указателей
- •Инициализация указателей
- •Лекция 5 Функции языка с
- •Объявление функции
- •Оператор return
- •Прототипы функций
- •Функции c произвольным числом параметров
- •Область действия и область видимости переменной
- •Классы памяти
- •Параметры и аргументы функции
- •Лекция 6 Типы, определяемые пользователями
- •Структура
- •Перечислимый тип
- •Переименование типов-typedef
- •Лекция 7 Модели памяти и препроцессор языка с Модели памяти
- •Препроцессор языка с
- •Директива #define
- •Список рекомендуемой литературы
- •Оглавление
- •Программирование на языках высокого уровня: с
- •428015 Г.Чебоксары, Московский просп., 15
Связь указателей и массивов
На языке С существует важная связь между массивами и указателями. В языке С принято, что имя массива - это адрес памяти, начиная с которого расположен массив, т. е. адpec первого элемента массива. Таким образом, если был объявлен массив int plus[10];, то plus является указателем на массив, точнее, на первый элемент массива. Операторы pl=plus; и pl=&plus[0]; приведут к одному и тому же результату. Для того чтобы получить значение 6-го элемента массива plus, можно написать plus[5] или *(р1+5). Результат будет один и тот же. Преимущество использования второго варианта состоит в том, что арифметические операции над указателями выполняются быстрее, если мы работаем с подряд идущими элементами массива. Если же выбор элементов массива случайный, то быстрее и более наглядна работа с индексами.
Очень часто приходится работать над обработкой текстов, т. е. с массивами строк. Как мы помним, в языке С строка - это массив символов, заканчивающийся нулевым байтом. Рассмотрим две программы, реализующие практически, одни и те же действия.
Программа 4.5:
#include<stdio.h>
#include<ctype.h>
main() {
char str[]="String From Letters in Different Registers";
/* Строка, Состоящая из Букв в Разных Регистрах; */
int i=1;
printf(“Строка Будет Напечатана Заглавными Буквами");
while (str[i])
printf("%c", toupper(str[ i++]));
Программа 4.6:
#include<stdio.h>
#include<ctype.h>
main() {
char *p;
char str[]="String From Letters in Different Register";
/*Строка, Состоящая из Букв в Разных Регистрах":*/
printf(“Строка будет напечатана строчными буквами");
p=str;
while(*p) printf("%c", tolower(*p++));
Если в этих примерах заменить строку на английском языке на строку, набранную русскими буквами, то никакого преобразования букв в строчные или, наоборот, в прописные не произойдет. Этo связано с тем, что стандартные функции toupper() и tolower() анализируют значение аргумента и возвращают то же самое значение, если он не является соответственно строчной или прописной буквой латинского алфавита. Если же аргумент является строчной буквой латинского алфавита, то значением функции toupper() будет соответствующая прописная буква (точнее, код этой буквы). Функция tolower() изменяет код лишь прописных букв латинского алфавита. Прототипы этих функций находятся в заголовочном файле ctype.h.
Массивы указателей
Указатели, как и переменные любого другого типа, могут объединяться в массивы. Объявление массива указателей на 10 целых чисел имеет вид int *x[10];
Каждому из элементов массива можно присвоить адрес, например, третьему элементу присвоим адрес целой переменной у: x[2]=&y; Чтобы найти значение переменной у, можно написать *х[2].
Приведем пример использования массива указателей. Чаще всего это бывает удобно при обработке массива строк.
Программа 4.7:
#include<stdio.h>
#includc<string.h>
#include<stdlib.h>
#include<conio.h>
main() {
char*ext[]=("exe", "com", "dat", "pas", "cpp");
char ch, sl[80];
for(;;)
{
do {
рrintf("Файлы с расширением:\n");
printf(“1.exe \n");
printf("2. com \n");
printf("3. dat\n");
рrintf("4. pas \n");
printf("5. cpp \n");
printf("6. cpp \n");
printf(“Ваш выбор: \n");
ch=getche();
printf(\n);}
while ((сh<’l’||(ch>'7'));
if(ch==”7”) break;
strcp(sl, "dir*.");
slrcat(sl. ext[ch-l]);
}
Здесь функция system() - библиотечная функция, которая заставляет операционную систему DOS выполнить команду, являющуюся аргументом этой функции.
Очень часто массив указателей используется, если надо иметь ссылки на стандартный набор строк. Например, если мы хотим хранить сообщения о возможных ошибках, это удобно сделать так: char *errors[]={"Cannot open file ", "Cannot close file”, “Allocation error”, “System error” };
При таком объявлении строчные константы будут занесены в раздел констант в памяти, массив указателей будет состоять из четырех элементов, под которые будет выделена память, и эти элементы будут инициализированы адресами, указывающими на начало этих строчных констант.
Вообще строчная константа в языке С ассоциируется с адресом начала строки в памяти, тип строки получается char* (указатель на тип char). Поэтому возможно и активно используется присваивание char *рс: рс = "Hello, World !";
В языке С возможна также ситуация, когда указатель указывает на указатель. В этом случае описание будет иметь вид inl **point;
