|
Передача структуры в функцию
Саму структуру нельзя использовать в качестве аргумента функции. 1. Можно передавать элемент структуры в качестве аргумента. Тогда функция не знает, что это структура. struct funds{ char* bank; float fonds; char* name; float savef; }stan={"ПРБ", 1023.87, «Иванов И.И.», 123,45}; float sum (float, float); void main(void){ printf ("У Иванова И.И.всего %.2f рубл.\n", sum(stan.fonds,stan.savef)); } float sum(float x, float y){ return(x+y); } Функция sum() не знает, что ей передается элементы структуры, важно, что они имеют тип float.
2. Если нужно, чтобы она воздействовала на элемент структуры, то нужно передвать адрес элемента и далее работать через указатель определенного типа. modify(&stan.savef);
3. Сообщение функции, что она имеет дело со структурой. Для этого нужно передать адрес структуры в качестве аргумента. struct funds {...} stan={...}; void main(void){ float sum (struct funds*); printf ("У Иванова И.И. %.2f рублей\n", sum(&stan)); } float sum (stuct funds* money){ return(money->fonds+money->savef); } Указатель money ссылается на структуру funds. В отличие от массива имя структуры не является её адресом, поэтому указываем адрес &stan.
4. Имеется массив структур. В этом случае имя массива является его адресом. struct funds {...}stans[2]={{...},{...}}; void main(void){ float sum (struct funds*); printf ("Всего капитала %.2f рублей\n", sum(stans)); } float sum(struct funds* money){ float summ; int i; for (i=0, summ=0;i<2; i++, money++) summ+=money->fonds+money->savef; return (summ); } money=&stan[0]; увеличивается money++, ссылаемся на stan[1].
Пример 1. Определить номер дня в году. struct date { int day; int month; int year; int yearday;}d={25,3,1999}; int date_tab[2][13]={{ 0,31,28,31,30,31,30,31,31,30,31,30,31}, { 0,31,29,31,30,31,30,31,31,30,31,30,31}}; int day_of_year(struct date *pd) { int i, day, l=0; day = pd->day; if(pd->year%4==0&&pd->year%100!=0||pd->year%400==0) //год высок. l=1; for(i=0; i< pd->month; i++) day+=date_tab[l][i]; return(day); } void main(void) { d.yearday=day_of_year(&d); - вызов функции. printf(“%d“, d.yearday); }
Объединения
Объединения - это средство, позволяющее запоминать данные различных типов в одном и том же месте памяти. Объединение позволяет создавать массив, состоящий из элементов одинакового размера, каждый из которых может содержать различные типы данных. Определяется также как и структура. Есть шаблон определения и переменные этого типа. union simbl { int digit; double bigfl; char letter; }; union simbl fit, save[10], *pu. Компилятор выделяет память по наибольшему из элементов объединения bigfl (double 8 байт), для массива структур save[10] будет выделено (10 x 8) байт. Как обращаться к элементу объеденения? fit.digit=23; (использ. 2байта) fit.bigfl=2.0 (23 стирается и записывается 2.0) fit.letter='a' (2.0 стирается и записывается'a'в 1байт) pu=&fit; x=pu->digit; Все типы объединения начинаются с одного и того же адреса и в данный момент можно обратиться только к одному данному объединения.
Синоним имени типа
Встречаются ситуации, когда удобно ввести синоним для имени стандартного типа или своего типа данных. Строится синоним имени с помощью ключевого слова typedef, сначала указывается старое имя, затем через пробел новое имя. Примеры: typedef int INT //INT-синоним типа int INT x, y;
typedef unsigned size_t; size_t x, y; //переменная типа unsigned
typedef char string[225]; string array; //char array[225];
1. Функция typedef только даёт имена типам данных, не создает новые. 2. Выполняется компилятором, а не препроцессором. 3. Более гибка, чем #define. Хочу тип real вместо float typedef float real; real x, y[5], *px; если определение расположено внутри функции, то область действия локальна, вне функции глобальна. typedef char* STRING //STRING-идинтификатор указателя на тип char. STRING name, sign; //char*name,*sign;
Определение именнованных констант
Существуют 3 вида именнованных констант: - имя любого массива или функции; - имена членов перечисления; - любое имя любого типа, в определении которого присутствует модификатор const. const i = 5; const char *ip = &i; Поскольку модификация такого объекта-константы запрещена, он должен быть инициализирован. const int *ip; //константой является объект, на который указывает указатель; int* const ip; //сам указатель является константой const char *pc = "Это строка"; pc[2] = 'a'; //ошибка pc = "Это другая строка"; //верно
char* const pc = "Это строка"; pc[2] = 'a'; //верно pc = "Это другая строка"; //ошибка
Использование const предпочтительнее по сравнению с #define, так как использование константы контролирует компилятор.
Перечисления
Используется ключевое слово enum. За ним указывают имя типа перечисления и перечисляют значения, которые может принимать этот тип. Спецификатор enum позволяет программисту создавать собственные типы. Пример:
enum weekDays {Monday, Tuesday, Wensday, Thursday, Friday};
Идентификаторы перечисления представляют собой целочисленные переменные, которые по умолчанию имеют значения 0,1,..., если не указаны другие значения.
weekDays days; Переменная days теперь может принимать одно из 5 значений. days = Wensday;
Пример 2. enum colors {Red=2, Green=3};
Пример 3. Элементам перечисления можно присваивать значения. Например: enum VIDEO_BASE_ADDRES { VGA_EGA=0xA000000, CGA=0xB800000, MONO=0xB000000};
Битовые поля
В некоторыя задачах для экономии памяти необходимо упаковывать несколько объектов в одно машинное слово. Битовые поля часто используются в устройствах, где используется словосостояние (готово, не готово). В Си для этого определяются поля и доступ к ним. Поле – это последовательность битов внутри одного целого значения. Синтаксис определения полей и доступ к ним основан на понятиях, соответствующих элементам структуры. Например, запись struct { unsigned a:8; unsigned b:6; unsigned c:2;}d; определяет структуру d, содержащую поле а – 8 битов, поле b – 6 битов, с – 2 бита. Число, следующее за двоеточием указывает число разрядов в поле. Поля описываются как unsigned, чтобы подчеркнуть, что это величины без знака. Отдельные поля теперь обозначаются как d.a, d.b, d.c. С полями можно выполнять различные операции. d.a= d.b=(d.c<<2)+6; Поля не могут переходить за границу слова в ЭВМ. Если же очередное поле не помещается в частично заполненное слово, то под него выделяется новое слово. Поля могут быть безымянными, для таких полей в описании структуры указывается только двоеточие и размер. Такие поля используются как заполнители. Для принудительного перехода на новое слово используется специальный размер 0. Например, в структуре struct {unsigned a:8; :2; unsigned b:6; :0; unsigned c:12;} d; второе поле используется как «заполнитель», а четвертое приводит к выделению нового слова для поля c. С битовыми полями можно производить различные операции (=, -, …), сдвига. Битовые поля и объединения можно применять для неявного преобразования типов.
Пример 1. Программа перевода даты создания файла из каталоговой записи в структурную переменную, то есть в нормальную форму.
struct DOS-DATE { unsigned int day:5; unsigned int month:4; unsigned int year:7;}; union DATE_CONV { unsigned int packed_date; struct DOS_DATE unpacked_date;}; typedef union DATE_CONV DATE void main(void) { struct ffblk ffblk; //структура в которую читается информация о //файле из каталога, описана в <dir.h> int done=findfirst(“*.*”, &ffblk,0); //ищет первый файл в каталоге, если //файл найден, то в done возвращается 0. if(!done) {//(!done) – это то же самое, что done= =0 DATE d; d.packed_date=ffblk.ff_date; printf(%2d/%2d/%4d”,d.unpacked_date,d.unpacked_month, d.unpacked_year+1980); } }
ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры... Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом... Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|