Язык Си - руководство для начинающих - M. УЭИТ
Шрифт:
Интервал:
Закладка:
Язык Си позволяет использовать одновременно более одного модификатора, что даст возможность создавать множество типов:
int board[8] [8]; /* массив массивов типа int */
int **ptr; /* указатель на указатель на тип int */
int *risks[10]; /* 10-элементный массив указателей на тип int */
int (*wisks) [10]; /* указатель на 10-элемснтный массив типа int */
int *oof[3] [4]: /* 3-элементныи массив указателей на 4-элементный
массив типа int */
int (*uuf) [3][4]; /* указатель на массив 3х4 типа int */
Для распутывания этих описаний нужно понять, в каком порядке следует применять модификаторы. Три правила помогут вам справиться с этим.
1. Чем ближе кодификатор стоит к идентификатору, тем выше его приоритет.
2. Модификатиры [ ] и ( ) имеют приоритет выше, чем *.
3. Круглые скобки используются для объединения частей выражения, имеющих самый высокий приоритет.
Давайте применим эти правила к описанию int *oof[3] [4];
* и [3] примыкают к oof и имеют более высокий приоритет, чем [4] (правило 1). [3] имеет приоритет более высокий, чем * (правило 2). Следовательно, oof является 3-элементным массивом (перпый МОДИФИКАТОР) указателей (второй модификатор) на 4-элементный массив (третий модификатор) типа int (описание типа).
В описании
int (*uuf)[3][4];
скобки говорят, что модификатор * должен иметь первый приоритет, а это делает uuf указателем, как показано в предыдущем описании. Эти правила создают также следующие типы:
char *fump( ); /* функция, возвращающая указатель на тип char */
char (*frump) ( ); /* указатель на функцию, возвращающую тип char */
char *flump ( ) [3] /* функция, возвращающая указатель на 3-элементный
массив типа char */
char *flimp[3] ( ) /* 3-элементный массив указателей на функцию, которая
возвращает тип char */
Если вы примените структуры к этим примерам, то увидите, что возможности для описаний действительно растут причудливо. А применения ... так и быть, МЫ оставим их для более опытных программистов.
Язык Си со структурами, объединениями и typedef дает нам средства для эффективной и мобильной обработки данных.
ЧТО ВЫ ДОЛЖНЫ БЫЛИ УЗНАТЬ В ЭТОЙ ГЛАВЕ
Что такое структурный шаблон, и как его определять
Что такое имя структуры и как оно используется
Как определить структурную переменную: struct car honda;
Как обратиться к элементу структуры: honda.mpg
Как обратиться к указателю на структуру: struct car *ptcar;
Как обратиться к элементу при помощи указателя: ptcar->mpg
Как передать в функцию элемент структуры: eval(honda.mpg)
Как сообщить функции о структуре: rate(&honda)
Как создать вложенную структуру
Как обратиться к элементу вложенной структуры: honda.civic.cost
Как создавать и использовать массивы структур: struct car gm[5];
Как создать объединение: подобно структуре
Как использовать typedef: typedef struct car CRATE;
ВОПРОСЫ И ОТВЕТЫ
Вопросы
1. Что неправильно в этом шаблоне?
structure {char itible;
int num [20];
char *togs;
};
2. Вот фрагмент программы; что она напечатает?
struct house {
float sqft;
int rooms;
int stories;
char *address; };
main ( ) {
static struct house fruzt = { 1560.0, 6, 1, " 22 Spiffo Road";
struct house *sign;
sign = &fruzt;
printf(" %d %dn" , fruzt.rooms, sign-> stories);
printf(" %sn", frurt.address);
prinlf(" %c %c n" sign- >address[3], fruzt.address[4]);
}
3. Придумайте структурный шаблон, который будет содержать название месяца, трехбуквенную аббревиатуру месяца, количество дней в месяце и номер месяца.
4. Определите массив, состоящий из двенадцати структур того же типа, что и в вопросе 3, и инициализируйте его для не високосного года.
5. Напишите функцию, которая получает номер месяца, а возвращает общее число дней года вплоть до этого месяца. Считайте, что структурный шаблон и массив из вопросов 3 и 4 описаны как внешние.
6. Взяв за основу нижеследующую функцию typedet, опишите 10-элементный массив указанной структуры. Затем, используя присваивание отдельного элемента попытайтесь описать третьим элементом массива линзу Ремаркатара с фокусным расстоянием 500 мм и апертурой f / 2.0.
typedef struct { /* описатель линзы */
float foclen; /* фокусное расстояние, мм */
float fstop; /* апертура */
char *brand; /* фирменная марка */ } LENS;
Ответы:
1. Должно быть ключевое слово struct, а не structure. Шаблон требует либо имени структуры перед открывающей скобкой или имени переменной после закрывающей скобки. Кроме того, точка с запятой должна стоять после *togs и в конце шаблона.
2.
6 1
22 Spiffo Road S p
Элемент fruzt.address является символьной строкой, а fruzt.address[4] является пятым элементом этого массива.
3.
struct month {
char name[10]; /* или char *name; */
char abbrev[4]; /* или char *abbrev; */
int days;
int monumb; };
4.
struct month months [12] = {
{" Январь" , " Янв" , 31, 1} , {" Февраль" , " Фев" , 28, 2} ,
и т. л. {"Декабрь", "Дек" , 31, 12}
5.
days(monlh);
inl month;
{
int index, tolal;
if(month < 1 || month > 12)
return (-1); /* признак ошибки */
else
for(index = 0, total = 0; index < month; index++)
total + = months [index].days;
return (total);}
Заметим, что index содержит номер месяца, уменьшенный на единицу, так как массивы начинаются с индекса 0; следовательно, мы используем выражение index < month вместо index <= month.
6.
ЛИНЗА tubby [10];
tubby [2].foclen = 300.0;
tubby [2].fstop = 2.0;
tubby [2].brand = "Рсмаркатар";
УПРАЖНЕНИЯ
1. Переделайте вопрос 5, используя в качестве аргумента написанное буквами название месяца вместо номера месяца. [Не забывайте о функции strcmp( ).]
2. Напишите программу, которая запрашивает у пользователя день, месяц и год. Месяц может обозначаться номером, названием месяца или его аббревиатурой. После работы программа выдает общее количество дней в году вплоть до данного дня.
3. Переделайте нашу программу инвентаризации книг таким образом, чтобы она печатала информацию о книгах, упорядоченную в алфавитном порядке по названиям книг, и затем печатала общую стоимость книг.
15. Библиотека языка Си и файлы ввода-вывода
БИБЛИОТЕКА ЯЗЫКА СИ
ФАЙЛЫ В ЯЗЫКЕ СИ
ФУНКЦИИ РАБОТЫ С ФАЙЛОМ
МАКРООПРЕДЕЛЕНИЯ ДЛЯ ПРОВЕРКИ СИМВОЛОВ
ФУНКЦИИ РАСПРЕДЕЛЕНИЯ ПАМЯТИ
Всякий раз, когда нам нужно использовать такие функции, как printf( ), getchar( ) и strlen( ), мы обращаемся в библиотеку языка Си. Она содержит множество функций и макроопределений. Библиотеки меняются от системы к системе, но есть ядро функций (называемое стандартной библиотекой), которое используется чаще всего. В этой главе мы рассмотрим пятнадцать наиболее общих из этих функций, уделяя больше внимания функциям ввода-вывода и использованию файлов.
Однако сначала давайте поговорим о том, как пользоваться библиотекой.
ДОСТУП В БИБЛИОТЕКУ ЯЗЫКА СИ
Получение доступа к библиотеке зависит от системы, поэтому вам нужно посмотреть в своей системе, как применять наиболее распространенные операторы. Во-первых, есть несколько различных мест расположения библиотечных функций. Например, getchar( ) обычно задают как макроопределение в файле stdio.h, в то время как strlen( ) обычно хранится в библиотечном файле. Во-вторых, различные системы имеют разные способы доступа к этим функциям. Вот три из них.
Автоматический доступ
Во многих больших системах UNIX вы только компилируете программы, а доступ к более общим библиотечным функциям выполняется автоматически.
Включение файла