} symtab [300];
для ссылки на ival необходимо написать symtab[i].u.ival,
а к первому элементу строки sval можно обратиться любым из двух следующих способов:
*symtab[i].u.sval,
symtab[i].u.sval[0].
Инициализировать объединение можно только значением, имеющим тип его первого члена.
# include <stdio.h> main(){
union tt{
char *fam; float num;
} gg = "gadina"; gg.fam="gaduka"; printf("%s\n",gg.fam); gg.num=45; printf("%f\n",gg.num); printf("%s\n",gg.fam); printf("%f\n",gg.num);
}
Поля битов - это некоторое множество битов, лежащих рядом внутри одного машинного слова. Длина машинного слова зависит от реализации. Синтаксис описания полей битов и доступа к ним также базируется на синтаксисе описания и обработки структурных переменных:
struct {
unsigned int a:1; unsigned int b:1; unsigned int c:2; } flags;
Тут описана переменная flags, которая содержит два однобитовых и одно двухбитовое поле. Числа, следующие за двоеточием, задают ширину поля. Поля, как правило, описываются как беззнаковые целые, но они могут быть и типа int.
На отдельные поля ссылаются точно так же, как на компоненты обычных структурных переменных (например, flags.a). Поля могут участвовать в арифметических операциях так же, как и обычные целые числа. Они не могут быть массивами, не имеют адресов, то есть к ним нельзя применить оператор &.
Тема 26. Переименование типов данных.
Программирование на языке высокого уровня 09.03.01 |
31 |
Язык С/С++ предоставляет программисту возможность помимо использования встроенных типов данных, переменных и массивов самому заводить новые типы данных, наиболее подходящие для конкретной задачи. Кроме того в языке существует возможность переименовать любой тип данных, как встроенный, так и определенный программистом. Для этой цели служит средство typedef. Например, описание
typedef int length;
делает имя length синонимом int. С этого момента тип length можно применять при описании, в операторе приведения и т.д., точно так же, как тип int:
length len, maxlen; length *mass;
Аналогично описание
typedef char * string;
делает string синонимом char *, то есть указателем на char, и правомерным будет его соответствующее использование.
Возможно использовать typedef и при работе со структурами: typedef struct point {
int x; int y;
}giena;
Врезультате создается новое название типа - giena, и возможно описание
giena x,y,z;
Следует подчеркнуть, что декларация typedef не создает новый тип, она лишь сообщает новое имя для уже существующего типа. Никакого нового смысла эти новые имена не несут, они описывают переменные в точности с теми же свойствами, как если бы они были объявлены напрямую без переименования типа. Тем не менее, существуют причины для использования в программах средства typedef. Давая типам данных в реальных программах имена, отражающие смысловое содержание предметной области, мы делаем программу более понятной как для самого автора, так и для программистов, которым придется вносить в нее коррективы впоследствии.
typedef int zarplata; typedef struct inform {
char * family; char * addres; int kod;
} information; zarplata x,y;
information a;
Программирование на языке высокого уровня 09.03.01 |
32 |
Раздел 4. Структурные особенности языка программирования С++, отсутствующие в С. Лекции
20-22.
Тема 27. Аргументы, используемые по умолчанию.
|
В прототипе функции С++ (кстати, в С++ наличие прототипа |
||||
функции является обязательным независимо от типа |
значения, |
||||
возвращаемого функцией) можно указывать |
значения по |
умолчанию |
|||
для |
некоторых |
параметров. |
Это |
позволяет |
пропускать |
соответствующие аргументы при вызове функции, а на их место компилятор подставит указанные при описании значения. Параметры со значениями по умолчанию должны стоять после всех остальных параметров в списке. При этом, если для какого-либо параметра задано значение по умолчанию, то необходимо указать и значения для всех тех параметров, которые стоят справа от него. Соответственно, если при вызове функции параметр опускается, то нужно опустить и все последующие аргументы. Очень важно, что аргументы по умолчанию задаются именно в прототипе, а не в заголовке функции.
Если задан прототип
void ShowMsg (char *msg, int x=0, int y=0);
то корректными будут следующие вызовы:
ShowMsg("Error: Out of Memory"); ShowMsg("Error: Vseh doloy",25); ShowMsg("Error: Domoy ohota",25,25);
А вызов ShowMsg("Error: Vse ravno",,25);
будет неверным.
Тема 28. Встроенные функции.
В С++ при определении функции можно использовать ключевое слово inline. Оно предписывает компилятору помещать расширение тела функции везде, где происходит обращение к ней, вместо того, чтобы генерировать код вызова. Обычно встроенными делаются относительно небольшие по размеру функции, так как их использование делает текст программы больше, хотя такая программа и выполняется быстрее. На содержимое функций, объявляемых как inline, существуют ограничения. Так, не допускается использование ключевого слова inline для функций
применяющих операторы цикла, операторы |
switch и goto; для |
|
функций |
имеющих тип не void и при этом не содержащих оператора |
|
return. |
Кроме того, определение встроенной функции должно |
|
Программирование на языке высокого уровня 09.03.01 |
33 |
|
обязательно предшествовать ее вызову. И вообще, компилятор может безо всяких предупреждений проигнорировать модификатор inline (аналогично модификатору register).
В случае если функция определена как inline, но при ее описании слово inline отсутствует, будет выдано сообщение об ошибке. Если же функция описана как inline, но ее вызов предшествует ее определению, то при этом вызове расширения данной функции как встроенной не произойдет.
# include <stdio.h> inline int max2(int,int); int max3(int,int,int); int main(void)
{int x=10; y=20; z=30; w=40; x=max3(x,z,w);
z=max2(x,y); //расширения не будет
printf("max(%d,%d)=%d\n",x,y,z); return 0;
}
inline int max2(int a, int b)
{return a>b?a:b; }
int max3(int a, int b, int c)
{b=max2(a,b); // будет расширение
return max2(c,b);
}
Тема 29. Ссылки.
В С++ используется видоизмененная форма указателя, называемая ссылкой. Для ссылки не требуется дополнительного пространства в памяти, так как она является просто другим именем или псевдонимом переменной. Для определения ссылки используется унарный оператор &.
# include <stdio.h> int zluka=5;
int &korova=zluka; int main(void) {
printf("zluka=%d\n",zluka); //zluka=5 korova=korova+3; printf("zluka=%d\n",zluka); //zluka=8 return 0; }
Основной смысл использования ссылок состоит в применении их
для параметров функций и для типов |
возвращаемых |
значений |
функций. В том же случае, когда ссылка определена как |
псевдоним |
|
Программирование на языке высокого уровня 09.03.01 |
|
34 |
переменной, при определении она должна быть инициализирована, если только она не объявлена как extern. Ссылке после инициализации не может быть присвоена другая переменная.
В С++ можно передавать параметры ссылкой. Вызов функции, ожидающей в качестве параметра ссылочную переменную, синтаксически не отличается от вызова, в котором параметр передается значением. Чтобы указать, что функция ожидает передачу параметра ссылкой, при описании при описании перед именем переменной ставится модификатор &. Например,
# include <stdio.h> |
|
main() { |
|
int j=10; |
|
void aaa(int); |
|
void bbb(int *); |
|
void ccc(int &); |
|
printf("j=%d\n",j); |
//j=10 |
aaa(j); |
|
printf("j=%d\n",j); |
//j=10 |
bbb(&j); |
|
printf("j=%d\n",j); |
//j=11 |
ccc(j); |
|
printf("j=%d\n",j); |
//j=12 |
return 0; } |
|
void aaa (int i) |
|
{i++;} |
|
void bbb (int *i) |
|
{(*i)++;} |
|
void ccc (int &i) |
|
{i++;} |
|
Главным преимуществом ссылок по сравнению с указателями является простота программы. Во-первых, вызывающей функции не
требуется применять |
операцию взятия адреса, а во-вторых, |
вызываемая функция |
избавлена от использования косвенных |
операций.
Ссылка может быть использована как тип, возвращаемый функцией. Это позволяет "присваивать функции значения".
# include <stdio.h> const int j=10;
int mass [j];
int & aaa (int i)
{return mass[i];} void main()
{for (int i=1;i<j;i++) aaa(i)=i*i;
Программирование на языке высокого уровня 09.03.01 |
35 |