![](/user_photo/2706_HbeT2.jpg)
6. Скалярные типы данных. Целый тип.
Типы данных делятся на 4 класса: скалярные, void, функции, агрегатные.
Скалярные – арифметические (целый, вещественный), указатели, перечислимые.
Для определения данных целого типа используются различные ключевые слова, которые определяют диапазон значений и размер области памяти, выделяемой под переменные (табл. 6).
Таблица 6
Тип |
Размер памяти в байтах |
Диапазон значений |
char |
1 |
от -128 до 127 |
int |
2 |
|
short |
2 |
от -32768 до 32767 |
long |
4 |
от -2147483648 до 2147483647 |
unsigned char |
1 |
oт 0 до 255 |
unsigned int |
2 |
|
unsigned short |
2 |
от 0 до 65535 |
unsigned long |
4 |
от 0 до 4 294 967 295 |
Следует сделать следующее замечание: в языке СИ не определено представление в памяти и диапазон значений для идентификаторов с модификаторами-типа int и unsigned int. Размер памяти для переменной с модификатором типа signed int определяется длиной машинного слова, которое имеет различный размер на разных машинах. Так, на 16-ти разрядных машинах размер слова равен 2-м байтам, на 32-х разрядных машинах соответственно 4-м байтам, т.е. тип int эквивалентен типам short int, или long int в зависимости от архитектуры используемой ПЭВМ. Таким образом, одна и та же программа может правильно работать на одном компьютере и неправильно на другом. Для определения длины памяти занимаемой переменной можно использовать операцию sizeof языка СИ, возвращающую значение длины указанного модификатора-типа.
Скалярные типы данных. Вещественный или символьный тип данных.
Для переменных, представляющих число с плавающей точкой используются следующие модификаторы- типа: float, double, long double (в некоторых реализациях языка long double СИ отсутствует).
Величина с модификатором-типа float занимает 4 байта. Из них 1 байт отводится для знака, 8 бит для избыточной экспоненты и 23 бита для мантиссы. Отметим, что старший бит мантиссы всегда равен 1, поэтому он не заполняется, в связи с этим диапазон значений переменной с плавающей точкой приблизительно равен от 3.14E-38 до 3.14E+38.
Величина типа double занимает 8 бит в памяти. Ее формат аналогичен формату float. Биты памяти распределяются следующим образом: 1 бит для знака, 11 бит для экспоненты и 52 бита для мантиссы. С учетом опущенного старшего бита мантиссы диапазон значений равен от 1.7E-308 до 1.7E+308.
7.Операции и приоритеты.
1 {} элементы массива
2 () функция
3 . обращение к полю структуры
4 указание на структуру
5 ++,--
6 size of() вычисление размеров объекта
7 (тип) преобразование типа
8
побитовое отрицание
9 ! логическое отрицание
10 – знак
11 & взятие адреса
12 * обращение по адресу
13 *,/,% остаток от деления]арифметические
14 +,- ]операции
15 <<,>> побитовые сдвиги
16 <,>,>=,<= операции сравнения
17 ==,!= равенство и неравенство
18 & побитовое «и»
19 ^ побитовое «или»
20 \ простое исключение «или»
21 && логическое «и»
22 ¦¦ логическое «или»
23 ?: условная операция
24 = присваивание
25 , аналог
8. Приведение и преобразование типов.
Для преобразования объектов одного типа в другой используется операция:
(тип) выражение;
int i,j;
float f;
i=(int)f;
f=(float)i;
или
int i=2;
long l=2;
double d;
float f;
d=(double)i * (double)l;
f=(float)d;
В данном примере величины i,l,d будут явно преобразовываться к указанным в круглых скобках типам.
Преобразование также происходит при присваивании, если тип левой и правой частей не совпадает.
Также преобразование происходит при арифметических операциях. Преобразование происходит к ближайшему общему типу.
9. Функции файлового ввода/вывода.
<stdio.h> - сюда входят эти функции.
Описание файловой переменной – FILE *f;
1) открытие файла – fopen(char name[], char f[]);
Все файлы делятся на двоичные и текстовые.
“b” – двоичный
“r” – открыть на чтение read
“w” – открыть на запись write
“a” – для добавления add
“rb”, “wb”, “ab” – открытие текстовых файлов / двоичных (?)
Если в процессе открытия файла – ошибка, возвращается нулевое указание.
if((f=fopen(“a.dat”, “rb”))==NULL){ printf(“невозможно открыть a.dat\n”);
exit():
}
2) fclose(char name[]);
fclose(f);
fcloseall() – закрытие всех файлов
10. Функции ввода-вывода на консоль.
3) fgetc(f) чтение из файла одного символа файла f
do {
ch=fgetc(f);
}while(ch!=EOF)
4) getchar(); чтение одного символа с клавы
5)fgets (st, n, f) читает из файла f строку n-символов.
do {
fgets(st, 80, f);
puts(st);
}while (!feof(f));
6) fgets(st) – ввод строки с клавы.
7) fputc(ch,f) – вывод одного символа в файл
8) putchar(ch) – вывод символа на экран
9) fputs(st,f); вывод строки в файл.
10) puts(st) вывод строки на экран.
11) rewind(f) переход в начало файла.
12) fread(void *, int n, int size, FILE *f)
из фала f считывается и по адресу p записывается не более n элементов size-размеров каждый. Функция возвращает число реально считанных элементов.
int m[1024];
n=fread(m, 1024, 2, f);
for(s=0, i=0; i<n; i++) st=m[i];
13) fwrite(void *, int n, int size, FILE *f)
14) fseek(FILE *f, long n, int w); движение по файлу.
w=0-начало
w=1-текущий размер
w=2-конец
fseek(f,0,0) – в начало файла
15) feof(f) проверка на конец файла.
16) ftell(f) – возвращает текущее положение в файле.
n=ftell(f);
11. Конструкции выбора.
1) if (условие) опер1;
else опер2;
2) Условные операторы.
результат = (выражение)? опер1 : опер2;
Если <выражение> не нулевое (истинное), то результату присваивается 1 значение <опер1>, иначе результату присваивается значение 2 <опер2>
if (a>b) max = a;
else max = b;
max = (a>b)? a : b;
printf(“max из a и b =%d”, (a>b)?a:b);
max=(a>c && a>b)? a : (b>c)? b : c;
3) switch – заменяет разветвленный многократный опер if.
switch (выражение) {
const 1: выражение 1;
const 2: выражение 2;
. . .
default : выражение n;
}
switch(ch) {
‘a’: ;
‘A’: puts(“пункт 1”),break;
default puts (“error”); }
12. Команды передачи управления.
1) return – две функции.
-
Возвращение значения из ф-ции.
-
для завершения ф-ции в любом ее месте.
Ф-ция exit завершает всю прогу независимо где она встретилась в проге, а опер return завершает лишь ф-цию, где он встретится.
int max(int a, int b) {
if(a>b) return a;
else return b; }
2) break – используется для выхода из цикла из цикла до его естественного завершения
Ввести с клавы 10 положительных чисел
for(i=0; i<10; i++) {
scanf(“%d”, &k);
if (k<0) break;
m[i]=k;
}
Если цикл вложеннный, то прерывается внутренний цикл.
3) continue – используется для пропуска ряда оперов в цикле. Пропускаются оперы со слова continue, кончается последним опером.
i=b;
while(i<10){
scanf(“%d”, &k);
if (k<0) continue;
m[i]=k;
i++;
}
4) goto – позволяет передать управление на любой опер в пределах одной и той же ф-ции.
i=0;
while (i<10){
scanf(“%d”, &n);
if (k<0) goto m1;
m[i]=k;
i++; m1:
}
13.Циклы
1. While (выражение) инструкция вычисляется выражение. Если выражение не =0, то выполняется инструкция вычисление выражения повторяются. Цикл продолжается, пока выражение не станет =0, после чего вычисление продолжается с точки, расп. После инструкции
а=10;
while(a){
a--;}
2. for(выражение1;выр2;выр3)
{Инструкция} или
Выр1;
While(выр2){
Инструкция
Выр3;}
А)выполняется 1 (инициализация параметров)
Б)выполняется 2 если оно не =0, то цикл продолжается,else цикл заканчивается
В) выполняется инструкция
Г)выполняется 3
For (i=0;I<=10;i++)
3.do while
Do{
Инструкция}
While(выражение) может не выполняться
Сначала выполняется инструкция, затем вычисляется выражение. Если оно true,то инструкция выполняется снова. Когда выражение = false, то цикл заканчивается, те указывается условие окончания цикла i=0 do{ i=i++ while(i!=10)
14. Модели памяти.
В Си в зависимости от размера 4-х видов памяти поддерживается 6 моделей памяти:
-
1вид данных, с которыми оперирует прога – код проги. Измеряется в байтах.
-
Статистические данные. Здесь хранится информация. – это данные, память под которые отводится компилятором. Объекты, описанные вне функции. (Переменные . . .).
-
Динамические данные. – данные, память под которые выделяется прогой или программером.
-
Стек. В нем располагаются объекты, описанные внутри функции. В стеке память выделяется при вызове функции и освобождается при ее завершении.
Си использует 6 моделей памяти, которые могут переключаться при компиляции проги:
-
Крошечная. 1вид+2вид+3вид+4вид=64к
-
Малая. 1=54к. 2+3+4=64к
-
Средняя. 1=1Мб. 2+3+4=64к
-
Компактная. 1=64к. 2=64к. 3=1Мб. 4=64к
-
Большая. 1=1Мб. 2=64к. 3=1Мб. 4=64к
-
Огромная. 1=1Мб. 2=1Мб. 3=1Мб.4=64к
15. Указатели, арифметические действия над указателями.
Указателем называется объект, содержащий адрес памяти. С помощью указателей можно создавать одномерные, двумерные и т.д. массивы, динамические структуры, т.е. получать доступ к любым адресам памяти.
Указатель содержит адрес в памяти. Его значение говорит о том, где расположен объект, а не о содержании объекта.
int *p; // p – указатель на объект целого типа
int i; // - переменная целого типа
char *c; // с – указатель на символ
char ch; // - сам символ
p=&i; // р присвоиить адрес значения i
ch=*c; // узнать, что в *c
& - взятие адреса
* - обращение по адресу
К указателю можно прибавлять или отнимать число. Сложение или вычитание производится в единицах того типа, к которому относится указатель.
Также можно вычитать из одного указателя другой. Разность будет равна количеству элементов, между этими двумя указателями (сколько элементов помещается).
int m[10], *z;
z=m+9; // z=&m[9]
*(m+9) m[9]
*m m[0]
16. Массивы. Инициализация массивов.
Массивы – статические и динамические.
int m1[10]; //статический
int *m2=(int *)malloc(2*10); // динамический
int *m3, n;
- - -
puts(“введите кол-во эл-тов в масс.”);
scanf(“%d”,&n);
m3=(int *) malloc (2*n);
m1[0]=m2[0]=m3[0];
Отличия между динамич. и статич. массивами.
-
Имя статического массива - указатель константы. Имя динамического – указатель переменной. В обоих случаях имя массива указывает на нулевой эл-т.
-
Под статистический массив память выделяется компилятором, а под динамический – программером по ходу выполнения проги.
(!)Можно в память наслаивать друг на лруга массивы различных видов.
int m[10];
char *ch;
ch=(char *)m;
ch[0]=0;
Инициализация массивов:
Начальное значение элементов массива можно перечислить через (,).
int m[5]={1,2,3,4,5};
int a[]={1,2,3};
17.Многомерные массивы.
Любой многомерный массив в СИ является линейным
Int*p;
P=(int*)m;
P[11]==m[3][2]
M[3][2]=>*(p+3*n+2) n-общее количество строк
1 Динамические
# int*m[256]- массив из указателей, каждый из них указывает на одномерный массив, размером 256
…
…
for (i=0; i<256;i++)
m1=(int*)malloc(256*siceof(int));
m[3][2]=>*(*(m+3)+2),где *(m+3) адрес начальной 3-ей строки
(*(m+3)+2)-адрес элемента [3][2]
*(*(m+3)+2)-сам элемент [3][2]
# int**m- указывает на адрес начального одномерного массива. Надо выделить память под массив указателей
M=(int**)malloc(N*siceof(int**));
For(i=0;i<m;i++);
M[i]=(int*)malloc(m*siceof(int)); m*..-количество элементов в строке
2 Свободные динамические массивы-массив, у которого длина строк различна
Int*m[]={{1,2,3},{1,2},{1}}; m-свободный массив указывает на начало этих строк. Пример: считать в файл свободный массив строк:
Char **m;
Char st[256];
File*f;
Void man(){
F=f open(“A.txt”,”r”);
While(!feof(f)){
Fgets(f,255 st);
N++;}
M=(int**)malloc(n*siceof(char*))rewind(f);
For (i=0;i<n;i++){
Fgets(‘f,255 st);}
3 Статические. При их инициализации обязательно явно указывается длина строки.
Int a [][3]={{1,2,3},{4,5,6}};
Int a [][3]={{1,2,3},{1,2},{1}};
18. Строки, функции и работа с ними
Char st[20]; -массив из символов. в СИ конец строки-символ с кодом 0
функции: #include<string.h>
1) strcat(s1,s2)-сцепляет 1 и 2
2) strcmp(s1,s2)-сравнивает 1 и 2по значениям одов символов до первого различия. Эта функция возвращает целое значение:
- s1<s2
+ s1>s2
0 s1=s2
3) strcpy(s1,s2)-s2 копируется в s1
4) strlen(st)- определяется для строки
19. Функции. Параметры.
Функция- это один из производных типов (как массив и указатели) или Функция- это min исполняемый модуль программы.
(Спецификация параметров) Тип или тело функции
Тип:void- для не возвращаемого значения, другой для возвращаемого функцией значения Char,int,double
Имя:main для основной функции другое, которое выбраль пользователь, не совпадает со служебными словами и с именами других объектов (функции) проги
Специализация параметров:пусто или список формальных параметров:
Тип имя
Тело функции:часть определения функции, ограниченной {} и расположенной за заголовком функции. Тело может быть либо составным оператором, либо блоком. При обращении к функции передаются её параметры- используется передача по значениям.