Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Константы






 

 

6.4.3.1 Целочисленные константы

 

 

Типы int и long.

Системы исчисления

В 10 с/с цифры от 0 до 9 не начинающиеся с 0

В 8 с/с цифры от 0 до 7, обязательно начинаются с 0

В 16 с/с цифры от 0 до 9, буквы A..F (a..f) начинаются с 0х или 0Х

 

Пример 6.4:

170 /*десятичная*/

0252 /*восьмиричная*/

0хАА /*шестнадцатиричная*/

170L /*десятичная длинная*/

0252L /*восьмиричная длинная*/

0ХAАL /*шестнадцатиричная длинная*/

Во внутреннем представлении, если целая константа превысила 16 разрядов – автоматически представляется как 32 разряда (10 с/с). Если значение 8-ой или
16-ой константы превысило наибольшее целое без знака, то оно также будет представлено, как длинное беззнаковое.


6.4.3.2 С плавающей точкой

 

 

У констант с плавающей точкой float обязательно должны быть либо десятичная точка, либо е (экспоненциальная часть):

314.15 e-2 = 3.1415 = 314*10-2

 

6.4.3.3 Символьная

 

 

Внутримашинное представление информации записывается для каждого символа, причем изображение символьной константы берется в ‘ ‘.

1) для представления “читаемых” (“печатных”) символов используются внутримашинные коды – ASCII, КОИ-8, ДКОИ.

2) Специальные символьные константы (ESС-последовательности):

- Апостроф \’

- Кавычки \”

- Пусто (нулевой символ) \0

- Новая строка \n

- Обратная косая \\

3) Последовательности трех восьмеричных символов: \ddd (код символа).

Пример 6.5:

‘M’ ‘m’ ‘П’ ‘п’

‘\n’ ‘\\’

‘\016’ = ‘f’

Символьная константа имеет тип int (т.к. есть расширенные коды в ASCII, размером в 2 байта).

6.4.3.4.Строковая константа

 

 

Последовательность символов кодов внутримашинного представления, заключенная в парные кавычки (“ ”).

 

Пример 6.6:

“MM” “”ПМ” “Informatique” “m” “o”

Строковая константа представляет собой массив символов, в конце которого вставлен код признака конца строки - \0.

“ПМ”

П М \0

 

 

6.4.3.5 Константное выражение

 

 

Оперирует только с константами.

Кроме арифметических констант могут быть использованы именованные константы.

#define < имя> < текст>

< имя> - символьное имя

< текст> - последовательность литер

Семантика:

Далее по тексту программы производиться замена < имя> на < текст>, кроме как:

- внутри строковых констант;

- если цепочка, составляющая имя, является частью определения другого имени.

Особенности синтаксиса:

- имя может содержать только из заглавные буквы;

- не нужно писать декларации;

- ее нужна; после #define.

 

Пример 6.7:

#define MAX 100

#define V_YEAR 1

После своего определения именованные константы могут использоваться в константных выражениях.

Пример 6.8:

#define MAX 100

float a[MAX]…

Пример 6.9:

#define V_YEAR 1

int days_of_year [31+28+V_YEAR+31+30+31+30+31+31+30+31+30+31];


7 ДЕКЛАРАЦИИ В СИ

 

 

7.1 Декларации – назначение и синтаксис

 

 

В Си переменные надо объявлять до первого использования.

 

Декларация:

1) специфицирует тип;

2) содержит список переменных этого типа;

3) возможна начальная инициализация;

4) возможен квалификатор константы (const).

 

Пример 7.1:

int up, down, step;

char c, str[101];

 

или

int up;

int down;

int step;

char c;

char str[101];

 

 

7.2 Инициализация

 

 

Инициализация (от англ. Initial – начальное) – это процесс придания переменным начальных значений при их объявлении. Записывается в Си в виде выражения после символа равно при декларации переменной:

char newline=’\n’;

Если обычная декларация только выделяет память для переменной, то декларация с инициализацией, записывает в память и соответствующую информацию.

Пример 7.2

int i =0;

int board=MAX+1;

float eps=1.0e-3;

char error[]=”Ошибка: ”;

 

О ш и б к а : \0

 

int kdm[12]={31, 28, 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

 

 

7.3 Квалификатор константы const

 

 

Квалификатор const записывается перед декларацией. Его используют для того, чтобы запретить возможность изменения значения этой переменной в программе.

Пример 7.3:

const float pi=3.1415;

const int kdm[12]={31, 28, 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

……

pi=3.14; /*нельзя*/

kdm[i]=kdm[i]+1; /*нельзя*/


8 ОПЕРАТОРЫ В ЯЗЫКЕ СИ

 

 

8.1Арифметические операторы

 

 

В языке Си привычные знаки операций называют операторами, а конструкции языка (ветвления, циклы) называют инструкциями.

Свойства операторов:

- арность (количество операндов);

- позиция (место по отношению к операндам);

- приоритет (важность, старшинство);

- ассоциативность (порядок выполнения операторов с олинаковым приоритетом).

1.Операторы +, -, /, *, % бинарные.(% - остаток от деления)

 

Оператор Целые Вещественные
+ Сложение Сложение
- Вычитание Вычитание
* Умножение Умножение
/ Деление нацело Деление нацело
% Остаток от Деления --------------------  

Пример 8.1:

year%4

 

Приоритет:

prio(+) = prio(-)

prio(*) = prio (/) = prio(%)

prio(*, /, %) > prio(+, -)

Для унарных +, -:

prio(унарных)> prio(*, /, %)

 

Ассоциативность

Ассоциативность определяет порядок выполнения операторов с одинаковым приоритетом. Все арифметические операторы левоассоциативные.

Пример 8.2:

8/2/2 è 4/2=2

 

 

8.2 Операторы отношения и сравнения на равенство

 

 

Бинарные операторы:

1) отношения: >, > =, <, < = (одинаковый приоритет);

2) сравнения на равенство:

==(равно)! =(неравно)

Приоритет одинаковый внутри группы.

prio(отношения)> prio(сравнения на равенство)

prio(отношения)< prio(арифметических)

 

Пример 8.3:

K+1< l+2 (k+1)< (l+2)

Year%4==0 (Равен ли остаток от деления year на 4 0?)

Все операторы сравнения и отношения вырабатывают значение истина и ложь. В языке Си:

- ложь – 0

- истина - ≠ 0

- 8.3Логические операторы

 

 

8.3.1 Бинарные операторы:

& & - логическое ‘и’

|| - логическое ‘или’

Вычисление результата логического выражения выполняется до тех пор, пока не вычислится истинность выражения (слева на право).

Результат & & есть “ложь”, как только первый попавшийся операнд есть “ложь”. Результат || есть “истина”, как только первый попавшийся операнд -“истина”.

Дальше вычисление не производится.

Свойства:

& & и || -левоассоциативные

prio(& &) = prio(||)

prio(& &) < prio (отношения, сравнения на равенство)

 

X& & Y

X Y И Л
И И Л
Л Л Л

 

X||Y

X Y И Л
И И И
Л И Л

 

Пример 8.4:

4 3 2 6 5 1 8 7 (приоритет)

Year%4==0& & year%100! =0||year%400==0

8.3.2 Унарный оператор

Логическое отрицание

не -!

 

 

0, если х ≠ 0

! х=

1, если х=0

prio(!)> prio(& &, ||)

Пример 8.5:

Эквивалентны:

res==0 и! res

 

 

8.4 Побитовые операторы

 

 

Применяется к целочисленным операндам (char, short, int, long) знаковым и без знаковым.

 

 

8.4.1 Бинарные

 

 

8.4.1.1 Побитовое И

&: используют для обнуления разрядов или бита внутри байта

X& Y

X Y    
     
     

Пример 8.6:

Значение выражения содержит 1 Maska1=017;

во всех разрядах, в которых ie1 и ie2 P=p& maska1;

содержит 1 и 0 во всех остальных разрядах

 

 

8.4.1.2 Побитовое ИЛИ

|: для установки разрядов в 1

X||Y

X Y    
     
     

 

Пример 8.7:

Значение выражения содержит 1 Maska2=03;

во всех разрядах, в которых ie1 или ie2 m=m& maska2;

содержит 1 и 0 во всех остальных разрядах

 

Следует отличать логические и побитовые операторы!!!

 

Пример 8.8:

X=1; y=2;

x& & y /*=1*/

x& y /*=0*/

 

8.4.1.3 Побитовое исключающее ИЛИ

^: 1- разные значения

0- остальные разряды


X ^ Y

X \ Y    
     
     

 

Пример 8.9:

x=0177;

y=01;

x^y /*0176*/;

 

8.4.1.4 Сдвиг влево

< < - правый операнд должен быть > 0

Это целое положительное число, указывающее на сколько битов необходимо сдвинуть левый операнд влево.

Пример 8.10

x=02; /*0102*/

y=x< < 1; /*01002=4*/

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

 

8.4.1.5 Сдвиг вправо

> > - правый операнд должен быть > 0

Это целое положительное число, указывающее на сколько битов необходимо сдвинуть левый операнд вправо.

Пример 8.11

x=06; /*1102*/

y=x> > 1; /*112=3*/

z=x> > 2; /*12*/

Сдвиг вправо соответствует делению нацело на степень двойки.

 

 

8.4.2 Унарные

 

Унарный оператор побитового отрицания ~

x ~x
   
   

Пример 8.12

c=c& ~03;

Значение выражения:

       

C_1 ……………………………………С_14 С_15 С_16

 

 

8.5 Операторы присваивания

 

 

Операторы присваивания имеют следующий вид

< e1> < op> =< e2> - выражение

< op> - бинарный оператор

+ % < < |

- > > ^

* &

/

Выполнение

< e1> =< e1> < op> < e2>

значки операторов присваивания

+= /= < < = & = ^=

-= %= > > = |=

Пример 8.14

x=15; x8=015;

y=8; y8=07;

z=5; z8=05;

x+=2; /*x=17*/

y-=7; /*y=1*/

z*=4; /*z=20*/

z/=2; /*z=10*/

z%=3; /*z=1*/

x8< < =2; /*x8=064*/

y8> > =1; /*y8=3*/

x8|=03; /*x8=067*/

x8^=07; /*x8=060*/

!!! Внимание!!!

x*=a+b (x=x*(a+b)

(x=x*a+b;

Все операторы правоассоциативные.

 

 

8.6 Инкрементные и декрементные операторы

 

 

Унарные

инкрементный ++: добавляет 1 к операнду;

декрементный --: вычитает 1 из оператора

необычность

префиксный ++(--) увеличивает (уменьшает) операнд до его использования

постфиксный ++(--) увеличивает (уменьшает) операнд после его использования

Пример 8.15:

 

x=2;

y=x++; /*y=x; x+=1;

y=2; x=3*/

x=2;

z=++x; /*x+=1; z=x;

x=3; z=3*/

Эти операторы можно применять только к переменным, но не к выражениям.

 

 

8.7 Преобразование типов

 

 

Преобразование (приведение) типов: приведение операндов разных типов к некоторому общему.

Существуют правила, согласно которым операнды приводятся к общему типу.

1) Для бинарных операторов:

а) если 1 из операндов имеет тип long double, то операнды приводятся к типу long double;

б) если 1 из операндов имеет тип double, то общий тип – double;

в) если 1 из операндов имеет тип float, то общий тип - float;

г) если 1 из операндов имеет тип short или int, то общий тип – int; (для целочисленных операндов);

д) если 1 из операндов имеет тип long, то общий тип – long, то общий тип- long (для целочисленных операндов).

2) При присваивании:

значение правой части приводится к типу левой части, это и будет типом результата.

а) char -> int (размножение знака)

б) int -> short

int -> char

long -> int

long -> char

(отбрасывание старших разрядов)

в) float -> int

int -> float

(преобразование типа с ПТ < -> целое)

г) double -> float (округление/отбрасывание)

3) При вызове функций (будет рассмотрено в соответствующей теме)

4) Явное задание приведения типов

Когда ни одно из вышеуказанных правил не выполняется, то используется оператор < тип>, который задаёт явное преобразование к явному типу данных.

- унарный;

- префиксный;

- правоассоциативный

Синтаксис:

(< имя_типа>) е,

где е – выражение

Семантика:

< е> приводится к заданному < типу>

 

Пример 8.19:

int x=16;

y=sqrt((double)x);

 


9 УПРАВЛЕНИЕ В СИ

 

Управление – определенный порядок выполнения вычислений в программе.

 

 

9.1 Инструкции и блоки

 

 

Если в конце выражения поставить ‘; ’, то выражение становится инструкцией.

< инструкция>:: =< выражение>;

Пример 9.1:

x=0 j++ /* выражения */

x=0; j++; /* инструкции */

Составная инструкция (блок).

< блок>:: ={ [< декларация> ]

< инструкция1>;

………………….

< инструкция n>;

}

Внутри блока разрешены как операторы декларации так и исполнимые операторы.

 

 

9.2 Инструкция if – else

 

 

Синтаксис

if(< выражение>) либо if (< выражение>)

< инструкция1> < инструкция1>

else < инструкция2>

Семантика

Вычисляется значение выражения, если значение выражения истинно, то выполняется < инструкция1>, если ложно то < инструкция2>

Пример 9.2:

int a, b, c; /* исходные данные */

int x; /* результат */

……..

if(a> b) /* вариант 1 */

if(a> c) x=a;

else x=c;

else if(b> c) x=b;

else x=c;

/* вариант 2 */

………………………..

x=a;

if (b> x) x=b;

if(c> x) x=c;

9.3Переключатель switch

Используется для разветвления алгоритма более чем на 2 направления.

Синтаксис

Switch(< выражение>)

{ case < константное выражение1>: < инструкции 1>

case< константное выражение n>: < инструкции n>

default: < инструкции>

}

Семантика

Каждая ветвь case помечена одной или несколькими целочисленными константами или константными выражениями.

Исполнение всей конструкции switch начинается с той ветви case, в которой константное выражение совпадает со значением выражения записанного после слова switch. Если не одна из констант не подходит, то выполняется ветвь помеченная default.Ветвь default необязательна, и если ее нет, то ничего не вычисляется. Ветви case и default можно размещать в любом порядке. Поскольку выбор любой из ветвей case выполняется как переход на метку, то после выполнения одной ветви case, программа переходит к выполнению следующей ветви. Если этот переход не устраивает, то ветвь case нужно завершить оператором break.

Пример 9.3:

/* kd – количество дней месяца */

if (j==1|| j==3|| j==5|| j==7|| j==8|| j==10|| j==12) kd=31;

else if(j==2) kd=28;

else kd=30;

Пример 9.4:

………………………………..

switch (j)

{

case 1: kd=31; break;

case 2: kd=28; break;

case 3: kd=31; break;

…………………………….

case 12: kd=31; break;

default: printf(”Ошибка”); break; }

Пример 9.5:

switch (j)

{

case 1: case 3: case 5: case 7: case 8: case 10: case 12: kd=31; break;

case 4: case 6: case 9: case 11: kd=30; break;

default: if (j==2) kd=28;

else printf(”Ошибка”); break; }

 

 

9.6 Цикл while

Синтаксис:

While (< выражение>)

< инструкция>

Аналог ”пока” языка алгоритмов. Это цикл с неизвестным количеством повторений, с предусловием.

Семантика:

Вычисляется выражение, если оно отлично от 0 (истинно),

то выполняется инструкция и снова переход на проверку выражения.

Как только выражение станет равным 0 цикл while завершается. Если необходимо в теле цикла выполнить больше чем 1 инструкцию, то надо взять в { }

Пример 9.6:

/* е в степени х (с точностью eps) */

float y, s,, eps, x;

int i, n;

………………………………………… /* Ввод х */

y=1; n=1; i=1; S=x;

while (s/n> eps)

{

y+=s/n;

i++;

n*=i;

s*=x;

}

9.7 Цикл for

Синтаксис

For (< выражение 1>; < выражение 2>; < выражение 3>)

< инструкция>

Это цикл с известным числом повторений.

Семантика

< выражение 1>

while(< выражение 2>)

{< инструкция >;

< выражение 3>;

}

< выражение 1> - инициализация

< выражение 2> - условие завершения цикла

< выражение 3> - изменение

Любое из этих 3 выражений может отсутствовать, но ‘; ’ обязательно!!!

Пример 9.7:

/* бесконечный цикл */

for(;;)

{……...}

Если опущены < выражение1> и < выражение3> - они не используются.

< выражение1> берется до цикла.

< выражение3> изменяется внутри цикла

Пример 9.8-9.9

#define N 10

float X[N]

int i;

float s;

………………………………..

s=0;

for(i=0; i< N; i++)

s+=X[i];

Либо:

for(s=0, i=0; i< N; i++)

s+=X[i];

Особенности цикла for в языке С:

Переменная цикла и ее предельное значение могут изменятся внутри цикла. По завершению цикла переменная цикла определена. В выражениях 1, 2 и 3 может быть использовано более одного выражения, разделенных оператором ‘, ’

‘, ’- бинарный, инфиксный, левоассоциативный оператор.

Приммер 9.10 Реверсировать массив.

0 1 2 3 4

1                    

 

#define N 10

…………….

float x[N];

int i, j;

float r;

…………….

For(i=0, j=N-1; i< j; i++, j--)

{

r=x[i];

x[i]=x[j];

x[j]=r;

}

 

9.6 Цикл do while

 

Синтаксис: do < инструкция> while (< выражение>)

- цикл с неизвестным числом повторений.

Семантика: 1.выполняется < инструкция>

2.вычисляется значение < выражения>

3.если < выражение> истинно(не равно 0), то снова переходим на пункт 1. Если < выражение> равно 0 (ложно) – конец цикла.

 

9.7 Инструкция break и continue

 

Break используется в циклах while, for, do while и в конструкции zwitch. В циклах использование break приводит к немедленному их завершению (до достижения предельного значения переменной цикла for или до достижения условия завершения цикла в while или do while).

Пример 9.11 Определить, является ли матрица А положительно определенной (все элементы больше 0).

Aij> 0, i принадлежит [1, m], j принадлежит [1, n]

#define N 10

#define M 15

float a[M][N];

int i, j;

int pr=1;

for (i=0; i< =M-1; i++)

for(j=0; j< N; j++)

if (a[i][j]< =0)

{ pr=0; break; }

if (pr) printf(“A - положительно определенная ”);

else printf(“A – не положительно определенная ”);

! Break завершает немедленно ближайший, охватывающий его цикл.

Continue вызывает переход к следующей итерации цикла: в for изменяет переменную цикла согласно закона, указанного в шапке цикла, в while, do while приводит к вычислению выражения, которое является условием продолжения цикла.

Пример 9.12. Найти сумму S отрицательных элементов массива x[N]

#define N 5

float x[N];

int i;

float s=0;

for(i=0; i< =N-1; i++) или for(i=0; i< N; i++)

if (x[i]< 0) s+=x[i]; {if (x[i]> =0)continue;

s+=x[i]; }

 

 


10 УКАЗАТЕЛИ И МАССИВЫ

 

10.1 Указатели

int x;

int *px; /* объявляется указатель на данное целого типа */

 

px=& x; /* указателю px присвоили адрес переменной x */

 

ПАМЯТЬ-массив последовательно проадресованных ячеек, с кото- рыми можно работать по одному и группами.

Указатель-группа ячеек памяти (2 или 4 байта), значениями которых является адрес.

Оператор & (унарный) выдаёт адрес объекта.

Пример 10.1:

p=& c; (р ссылается на переменную с)

pi=& i; (pi ссылается на переменную i)

Применяется только к операндам которые находятся в памятии (переменные и элементы массива)

Не могут быть применины к константам и выражениям

 

Унарный оператор * -оператор раскрытия ссылки,

применяется только к указателям. Результат - объект, на который ссылается указатель

Пример 10.2:

int a=1, b=2, z[5];

int *ip; /* объявляем указатель на переменную целого

типа */

ip=& a; /* указатель ip ссылается на переменную a */

b=*ip; /* b=1 */

*ip=0; /* a=0 */

ip=& z[2] /* ip указывает на z[2] */

Указатель ссылается только на объекты заданного типа (кроме void)

При объявлении указателя можно написать указатель на тип void:

void *p;

но потом применять оператор разоименования (*) нельзя

Пусть

int a=1;

int *ip; => Используем *ip везде, где допустимо использовать a:

ip=& a;

- *ip=*ip+10; /* a+=10 */

- y=*ip+1; /* y=11+1 */

- *ip+=1; /* 11+1=12 */

 

- +*ip; /* 12+1=13 */

- (*ip)++; /* 13+1=14 */

-! *ip++; /* изменяется сам указатель, а не то

значение на которое он ссылается */

В этом примере увелечение самого указателя на 1 приводит к тому, что ссылается на следующий элемент того типа, какой был

заявлен в деклорации.

Указатель есть переменная, а поэтому он может встречатся в программе и без оператора *

Пример10.3:

int a;

int *ip, *ir;

ir=& a;

ir=ip;

10.2 Связь между указателями и массивом

В языке C связь между указателями и массивом очень тесная, так как любая операция взятия элемента массива может быть выполнена с помощью оператора *(!!! более того * выполняется быстрее)

 

[ ] º *

int a[5];

i-й элемент: a[i]

С указателем:

int *pa

pa=& a[0];

x=*pa => x=a[0];

Адресная арифметика:

Если указатель pa указывает на некоторый элемент массива, то выражение pa+1 указывает на следующий элемент массива, pa+i – на i-й после pa, pa-1 – на предыдущий (перед pa).

Если pa=& a[0], то *(pa+1)~a[1]

pa+i~ адрес a[i]

*(pa+i)~a[i]

Пример 10.4:

int *pa;

int a[5]= -1, -10, -100, -1000, -10000;

int a1, a2;

pa=& a[0];

a1=*(pa+1); /* a1=-10 */

a2=*(pa+2); /* a2=-100 */

 

Связь между адресной арифметикой и индексированием массива

 

Значение переменой или выражения типа массива есть адрес нулевого элемента этого массива.

ПРИМЕР 10-5

int a[5], * pa, *pm

pa=& a[0]: pm=a;

Эквивалентны

a[i] | *(a+1)

& a[i] | a+i

pa[i] *(pa+i)

Указатели группируються обычные элементы.Указатели также можно индексировать.Тогда *(pa+i) pa[i].Различия между именем.

I 10-4 Различия между именем масства и указателем(в роли имени массива)

Указатель=переменная

-допустимо

int*pa; int a[5]

pa=a;

pa++;

-недопустимо

int*pa;

int a[5];

a=pa;

a++;

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.