Связь указателей и массивов

В С существует важная связь между массивами и указателями. В С принято, что имя массива – это адрес памяти, начиная с которого расположен массив, то есть адрес первого элемента массива. Таким образом, если был объявлен массив int plus[10];то plus является указателем на массив, точнее, на первый элемент массива. Операторы p1=plus;иp1=&plus[0];приведут к одному и тому же результату. Для того, чтобы получить значение 6-го элемента массива можно написать plus[5] или *(p1+5)и результат будет один и тот же. Преимущество использования второго варианта состоит в том, что арифметические операции над указателями выполняются быстрее, если мы работаем с подряд идущими элементами массива. Если же выбор элементов массива случаен, то быстрее и более наглядна работа с индексами.

Примеры работы со строками:

#include <stdio.h>

#include <ctype.h>

Void main(void)

{

char str[]=”String From Letters in Different Registers”;

Int i;

printf(“Строка Будет Напечатана Заглавными Буквами”);

while(str[i])

printf(“%c”,toupper(str[i++]));

}

#include <stdio.h>

#include <ctype.h>

Void main(void)

{

char str[]=”String From Letters in Different Registers”;

Int i;

printf(“Строка Будет Напечатана Строчными Буквами”);

p=str;

while(*p)

printf(“%c”,tolower(*p++));

} //В первом примере вывод текста заглавными буквами, во втором, строчными.

Массивы указателей

Указатели, как и переменные любого другого типа, могут объединяться в массивы. Объявление указателей на 10 целых чисел имеет вид int *x[10];

Каждому из элементов массива можно присвоить адрес: например, третьему элементу присвоим адрес целой переменной y: x[2]=&y; Чтобы найти значение переменой y, можно написать *x[2].

#include <stdio.h>// Пример использования массива указателей при обработке массива строк.

#include <string.h>

#include <stdlib.h>

#include <conio.h>

Void main(void)

{

char *ext[]={“exe”,”com”,”dat”,”c”,”pas”,”cpp”};

char ch,sl[80];

For(;;)

{ do

{ printf(“Файлы с расширением:\n”);

printf(“1, exe\n”);

printf(“2, com\n”);

printf(“3, dat\n”);

printf(“4, c\n”);

printf(“5, pas\n”);

printf(“6, cpp\n”);

printf(“7, guit\n”);

printf(“Ваш выбор:\n”);

ch=getche();

printf(“\n”);

}

while((ch<’1’||(ch>’7’));

if (ch==’7’) break;

strcpy(sl,”dir *.”);

strcat(sl,ext[ch-1]);

System(sl);

}

}

Очень часто массив указателей используется, если надо иметь ссылки на стандартный набор строк. Например, если мы хотим хранить сообщения о возможных ошибках, то это удобно сделать так:

char *errors[]={“Cannot open file”,“Cannot close file”,“Allocation error”,“System error”};

При таком объявлении строчные константы будут занесены в раздел констант в памяти, массив указателей будет состоять из четырех элементов, под которые будет выделена память, и эти элементы будут инициализированы адресами, указывающими на начало этих строчных констант. Вообще строчная константа в языке в языке С ассоциируется с адресом начала строки в памяти, тип строки получается char* (указатель на тип char). Поэтому возможно и активно используется присваивание:

char *pc; pc=”hello, World!”;

В языке С возможна также ситуация, когда указатель указывает на указатель. В этом случае описание будет иметь следующий вид: int **point;

Указатель

Адрес

|

|

Указатель

Адрес

|

Переменная

Значение

 

pointимеет тип указатель на int. Соответственно, чтобы получить целочисленное значение переменной, на которую указывает point, надо в выражении использовать **point.

Типы, определяемые пользователем

Кроме известных типов данных язык С позволяет создавать еще 5 типов данных:

- структуры (structure);

- объединения (union);

- перечисляемый тип (enumeration);

- поля битов (bit fields);

- с помощью оператора typedef создается новое имя (псевдоним) для уже существующего типа.

Структура

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

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

Struct student

{

char name[30];

Int kurs;

char group[3];

Int index;

}

В данном случае под именем student задан шаблон структуры и определен новый тип struct student.Выделение памяти не происходит. Для того, чтобы объявить конкретные переменные типа struct student, надо написать