Для ботаников и лентяев

aa1
aa2
aa3

СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ (С)

1. Язык Си. История возникновенияЯзык Си. Алфавит и словарь языка Си. Структура программы на языке Си.

2.Алфавит и словарь языка Си. Структура программы на языке Си

3.Представление данных в Си

4.Особенности представления целочисленных данных в Си

5.Данные символьного и логического типа в Си

6.Представление вещественных типов данных в Си

7. Совместимость типов. Правила автоматического приведения типов

8. Переменные и константы. Явное приведение типов

9.Арифметические операции; Особенности выполнения арифметических операций

10.Логические операции и операции отношения

11.Логические побитовые операции и операции сдвига

12.Библиотека элементарных математических функций

13.Операции инкремента и декремента. операция присваивания

14.Средства форматированного ввода данных

15.Средства форматированного вывода данных

16.Оператор выбора if. Простой и составной оператор

17.Оператор множественного выбора switch.

18.Циклы: организация циклов for

19.Циклы while и do-while

20.Указатели в Си; назначение типа указателя

21.Операции над указателями. Адресная арифметика

22.Массивы в Си. Связь между указателями и массивами

23. Одномерные массивы. Размерность массива. Инициализация массива

24. Работа с многомерными массивами

25. Связь между одномерными и многомерными массивами. Способы доступа к элементам массива

26. Массивы указателей; указатель на указатель

27. Строковые данные. Строки и символьные массивы; инициализация

28.Функции обработки строк: копирование данных строки

29.Функции обработки строк: изменение строк

30. Функции обработки строк: сравнение строк

31. Функции обработки строк: поиск в строке

32. Функции обработки строк: средства преобразования числовых данных в строки и обратно

33. Функции работы с символьными данными (ctype.h)

34. Структуры. Доступ к элементам; размещение в памяти

35. Вложенные структуры; структуры и указатели; массивы структур

36. Функции пользователя: прототипы функций. Передача параметров в функцию

37. Функции пользователя с переменным числом аргументов

38. Функции пользователя: использование рекурсии

39. Файловый ввод/вывод в С: понятие файлового потока, файловый буфер

40. Файловый ввод/вывод в С: средства буферизованного доступа к файлам

41. Файловый ввод/вывод в С: средства форматированного ввода/вывода

42.Файловый ввод/вывод в С: средства неформатированного и блочного ввода/вывода

43.Файловый ввод/вывод в С: управление файловым указателем

44.Поиск файлов и директорий; управление файлами и директориями

45. Виды взаимодействия между процессами в UNIX; организация полудуплексных каналов

46.Динамическое выделение памяти: функции работы с «кучей

47. Директивы препроцессора: условная трансляция

48. Управление процессами в С

49. Небуферизованный доступ к файлам в стиле UNIX

50. Способы организации полудуплексного канала для взаимодействия с дочерним процессом

1. ЯЗЫК СИ. ИСТОРИЯ ВОЗНИКНОВЕНИЯЯЗЫК СИ. АЛФАВИТ И СЛОВАРЬ ЯЗЫКА СИ. СТРУКТУРА ПРОГРАММЫ НА ЯЗЫКЕ СИ.

Язык С был создан в 71 г. 20 века. Разработчик языка Денис Ритчи. Из конструкции языка можно сделать вывод, что автор знал Аlgol, PASCAL, PL1.

С был разработан спец. для создания ОС UNIX. UNIX оказалась первой коммерческой ОС написанной на ЯВУ (С). Поскольку предполагалось, что UNIX будет переноситься на различные аппаратные платформы в языке С с самого начала была предусмотрена возможность создания просплатформенных приложений – программ, кот. без изменений могут быть перекомпилированы под другую аппаратную платформу.

Любая программа на языке С должна начинаться с одной или нескольких строк, подключающих необходимые библиотеки.

# include <имя библиотеки>

#include

Любая прога С традиционно имеет в качестве расширения файла имеет букву «С»

Базовой оценкой кода на С явл. ф-ция, поэтому любая программа должна состоять из одной функции – функция с именем main. Начало этой функции – точка входа в программу. Возвращаемое значение этой функции и есть то значение которое программа по завершению передаёт ОС.

Типичная программа:

Main()

{

Return(0)

}

{} – вместо begin и end

Строка return(0) возвращает код выхода из программы.

Очень важное замечание:

C различает прописные и строчные буквы. Поэтому в программе очень важно их не перепутать.

Var1 и VAR1 – две разные переменные.

2.АЛФАВИТ И СЛОВАРЬ ЯЗЫКА СИ. СТРУКТУРА ПРОГРАММЫ НА ЯЗЫКЕ СИ

3.ПРЕДСТАВЛЕНИЕ ДАННЫХ В СИ

Константы в С немеют имён, а запись непосредственно в виде значений.

Тип данных, к которому принадлежит константа, определяется по значению.

При объявлении переменных в С тип всегда указывается явно. Несколько переменных одного типа можно объявить через запятую. При объявлении переменной можно сразу присваивать начальное значение.

Пример:

Char a,b,c;

Int a=0;

4.ОСОБЕННОСТИ ПРЕДСТАВЛЕНИЯ ЦЕЛОЧИСЛЕННЫХ ДАННЫХ В СИ

В архитектуре IA16 (DOS) занимает 16 бит бывает знаковый, бесзнаковый.

Signed int var1;

Unsigned int var2;

Знаковые находятся в диапазоне -32786-+32767.

Длинное целое

Long int ?? Long – в два раза больше чем int.

Unsigned long v1;

Char занимает 1 байт.

Кроме длинного целого longint в С есть ещё shortint или short .

В 16 –и битной структуре ничем не отличается от простого int. Поэтому в IA16 особо не используются.

5.ДАННЫЕ СИМВОЛЬНОГО И ЛОГИЧЕСКОГО ТИПА В СИ

В языке С символьного типа нету. При необходимости передавать символы используют переменные целого типа – char или int. В этих переменных храняться ASCII код символа. Символьные константы существуют и записываются в кавычках ‘A’,…..

Символьная константа – константа символьного типа.

В языке С логических типов нет.

Для представления логических данных используют целые числа , 0 – false все остальные соответственно true

6.ПРЕДСТАВЛЕНИЕ ВЕЩЕСТВЕННЫХ ТИПОВ ДАННЫХ В СИ

В языке С вещественные типы есть. Используются в формате с плавающей точкой.

С=М*2^p

Float

Double

LongDouble

- float занимает 32 бита. Точность 7 цифр, диапазон +/-3.4*10^(+/-38)

- double занимает 64 бита. Точность 15 цифр, диапазон +/-1.7*10^(+/-308)

- longdouble занимает 80 бита. Точность 19 цифр, диапазон +/-3.4*10^(+/-4932)

Как и в pascal вещественные числа хранятся в нормализованной форме.

При нарушении нормализации мантиссу нормализуют, т.е. сдвигают в лево до тех пор пока старшей цифрой мантиссы не явл. единица. Каждая операция сдвига сопровождается уменьшением порядка на единицу.

7. СОВМЕСТИМОСТЬ ТИПОВ. ПРАВИЛА АВТОМАТИЧЕСКОГО ПРИВЕДЕНИЯ ТИПОВ

Простая форма: При смешивании различных типов в выражении меньшие типы приводятся к большим.

Сложная форма: (более подробные правила приведения типов)

1.char и int свободно смешиваются. char автоматически становится int.

Арифметические операции «+», «*» и т.д. работают следующим образом:

‘A’*0.128=64,999*0,128

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

2.Если один оператор имеет тип unsigned то другой операнд также преобразуется к беззнаковому типу.

3.Преобразования возникают также при присваивании. При сужающем преобразовании вещ. Типы округляются а в целых типах отбрасываются лишние биты старших порядков.

4.В любом месте можно производить явное приведение типов указав перед приводимым объектом значение нужного типа в круглых скобках 0.4+(double)’w’

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

8. ПЕРЕМЕННЫЕ И КОНСТАНТЫ. ЯВНОЕ ПРИВЕДЕНИЕ ТИПОВ Переменные и константы являются основными объектами,которыми оперирует программа. Описания перечисляют переменные, которые будут использоваться, указывают их тип и, возможно,их начальные значения. Константы в C не имеют имён, а записываются непосредственно в виде значений. Тип данных, которому принадлежит константа определяется по её значению. При объявлении переменных тип всегда объявляется ЯВНО Имя типа_Имя переменной имя переменной можно сразу присваивать начальное значение.

9.АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ; ОСОБЕННОСТИ ВЫПОЛНЕНИЯ АРИФМЕТИЧЕСКИХ ОПЕРАЦИЙ *,/,+,-,% %-остаток от ведения =-присваивание Присваивание анализируется справа налево. Кроме того ‘=’ имеет возвращаемое значение равное результату операции. Бинарными арифметическими операциями являются +, -, *, / и операция деления по модулю %. Имеется унарная операция -, но не существует унарной операции +. При делении целых дробная часть отбрасывается. Выражение х % y дает остаток от деления х на y и, следовательно, равно нулю, когда х делится на y точно. Oперацию % нельзя использовать с типами float или double. Операции + и - имеют одинаковое старшинство, которое младше одинакового уровня старшинства операций *, / и %, которые в свою очередь младше унарного минуса. Арифметические операции группируются слева направо. . Порядок выполнения ассоциативных и коммутативных операций типа + и - не фиксируется; компилятор может перегруппировывать даже заключенные в круглые скобки выражения, связанные такими операциями. Таким образом, а+(b+c) может быть вычислено как (a+b)+c. Это редко приводит к какому-либо расхождению, но если необходимо обеспечить строго определенный порядок, то нужно использовать явные промежуточные переменные. Действия, предпринимаемые при переполнении и антипереполнении (т.е. При получении слишком маленького по абсолютной величине числа), зависят от используемой машины. A=b=c=0 A=b=0 A=0 float a a=2/3 Результат a=0 Float a=2.0/3.0

10.ЛОГИЧЕСКИЕ ОПЕРАЦИИ И ОПЕРАЦИИ ОТНОШЕНИЯ Операциями отношения являются = => > =< < все они имеют одинаковое старшинство. Непосредственно за ними по уровню старшинства следуют операции равенства и неравенства: == != которые тоже имеют одинаковое старшинство. Выражения, связанные операциями && и ||, вычисляются слева направо, причем их рассмотрение прекращается сразу же как только становится ясно, будет ли результат истиной или ложью. Учет этих свойств очень существенен для написания правильно работающих программ.

11.ЛОГИЧЕСКИЕ ПОБИТОВЫЕ ОПЕРАЦИИ И ОПЕРАЦИИ СДВИГА в языке предусмотрен ряд операций для работы с битами; эти операции нельзя применять к переменным типа float или double. & Побитовое and | побитовое включающее or ^ побитовое исключающее or << сдвиг влево >> сдвиг вправо \^ дополнение (унарная операция) побитовая операция and часто используется для маскирования некоторого множества битов; например, оператор c = n & 0177 передает в 'с' семь младших битов n , полагая остальные равными нулю. Операция | побитового or используется для включения битов: c = x | mask устанавливает на единицу те биты в х , которые равны единице в mask. Следует быть внимательным и отличать побитовые операции & и | от логических связок && и || , которые подразумевают вычисление значения истинности слева направо. Например, если х=1, а y=2, то значение х&y равно нулю , в то время как значение x&&y равно единице. Операции сдвига << и >> осуществляют соответственно сдвиг влево и вправо своего левого операнда на число битовых позиций, задаваемых правым операндом. Таким образом , х<<2 сдвигает х влево на две позиции, заполняя освобождающиеся биты нулями, что эквивалентно умножению на 4. Сдвиг вправо величины без знака заполняет освобождающиеся биты на некоторых машинах, таких как PDP-11, заполняются содержанием знакового бита /"арифметический сдвиг"/, а на других - нулем /"логический сдвиг"/. Унарная операция ~ дает дополнение к целому; это означает , что каждый бит со значением 1 получает значение 0 и наоборот.

12.БИБЛИОТЕКА ЭЛЕМЕНТАРНЫХ МАТЕМАТИЧЕСКИХ ФУНКЦИЙ Библиотекой элементарных математических функций является math.h Вот его основные функции: abs-модуль числа,acos –аркосинус, asin-арксинус, atan -арктангенс atof –строковый тип во float, cos-косинус числа, cosh-гиперболический косинус, exp-экспонента, log-Логарифм функции Ln(x), log10-Логарифм функции Log10(x), sqrt-корень, sin-синус, tan-тангенс, sinh-гиперболический синус, tanh-гиперболический тангенс

13.ОПЕРАЦИИ ИНКРЕМЕНТА И ДЕКРЕМЕНТА. ОПЕРАЦИЯ ПРИСВАИВАНИЯ i++ i=i+1 операция инкремента i-- i=i-1 операция декремента i+=x i=i+x i*=x i=i*x -=,/= ++, -- бывает в префиксной и постфиксной форме ++x префиксной x++ постфиксной Постфиксная форма модифицирует переменную после вычисления выражения, в котором она встретилась; префиксная – до вычисления выражения: i=1 printf(“%d”,++i) printf(“%d”,i) вывод 2 2 i=1 printf(“%d”,i++) printf(“%d”,i) вывод 1 2 Для того, чтобы цикл for работал как обычный цикл с заданным числом повторений, нужно написать примерно следующее: For (i=1,i<10,i++) Printf(“%d”,i); Выводит на экран цифры от 1 до 9: For (i=1;i<10;printf(“%d”,i),i++); For (i=1;i<10;printf(“%d”,i)); Если в выражении нет других операторов, кроме ++ (- -), то нет разницы записывать его до или после переменной. Break прекращает выполнение цикла на совсем Continue прекращает выполнение цикла в данной итерации и переходит сразу на следующую. Переменную цикла можно менять внутри цикла.

14.СРЕДСТВА ФОРМАТИРОВАННОГО ВВОДА ДАННЫХ Для ввода с клавиатуры выполняется scanf(формат,..) Первой строка формата, далее список переменных в которых вводятся значения с клавиатуры, перед каждой переменной должен стоять & (кроме строковых). В строке формата игнорируется всё, кроме спецификаторов типа: scanf(“%d %d”,&i,&j) (& - взять адрес объекта) В функции scanf есть одна особенность: если в качестве аргумента используется строковая переменная (одна - несколько) scanf самовольно проводит синтаксический анализ введенной с клавиатуры строки, разбивает её на отдельные слова и передает каждой строковой переменной по одному слову.

15.СРЕДСТВА ФОРМАТИРОВАННОГО ВЫВОДА ДАННЫХ Для вывода на дисплей служит функция printf(формат, …) может иметь переменное число аргументов, первым аргументом всегда идет строка формата, за ней выводятся на экран переменные. Строка формата содержит объекты 3х типов: обычные символы, которые просто выводятся на экран. спецификатор преобразования, вместо которого на экран выводятся переменные из списка аргументов функции. Спецификатор преобразования начинается со знака % и заканчивается символом, обозначающим тип вводимого аргумента. Между % и этим символом можно указывать ширину поля ввода, выравнивание, кол-во знаков после запятой и т.д. Наиболее распространенные спецификаторы преобразования: %s – строка символов %c – один символ %d – целое число в десят.системе %o – целое число в воьмиричной системе %x – целое число в шестнадцатиричной системе %f – вещественное число с плавающей точкой (float) %u – беззнаковое целое Для вывода типов long и double после % добавляется буква l. %ld – тип long Функция printf использует управл.строку, чтобы определить сколько ей передали аргументов поэтому каждому спецификатору типа должен соответ. аргумент соответ. типа Для вывода на экран знака % в строке форм. надо написать: %% Int i=1,j=0;float q=0.1; Printf(“%d-%d=%f !!!”,I,j,q) Printf(“Hello world!”); 3. Управляющие символы Начинаются со знака \ за которым следует буква, транслятор заменяет каждую управляющую последовательность кодом некоторого спец. символа, наиболее популярны ‘\n’ переход на новую строку. В разных ОС \h генерирует другие коды символов. С точки зрения C \n считается одним символом, независимо от того, что на самом деле выводится на экран. \t – символ табуляции. \a – звуковой сигнал printf(“%c”,32) – выводи символ по ASCii коду для вывода символа ‘\’ необходимо ‘\\’

16.ОПЕРАТОР ВЫБОРА IF. ПРОСТОЙ И СОСТАВНОЙ ОПЕРАТОР if (условие) ветвь 1; if (условие) ветвь 1 else ветвь 2 Если ветвь состоит из нескольких операций их берут в {}.

17.ОПЕРАТОР МНОЖЕСТВЕННОГО ВЫБОРА SWITCH. Позволяет выбрать одну из нескольких альтернатив Switch (селектор) { case константа1:вариант1;break; … case константа n; вариант n; break; default: вариант n+1;break; } В операторе switch вычисляется целое выражение в скобках, затем его значении сравнивается со всеми константами (константами выражения). При совпадении выполняется соответ.вариант. Вариант с ключевым словом default выполняется если ни один из вариантов не подошел, ветвь default может отсутствовать. Команда break также может отсутствовать, но если после выбранной ветки не было слова break, то следом за ней выполняется подряд всё остальные ветви до тех пор пока break где-нибудь не встретится или пока не закончится switch. Switch (c) { case 1:printd(“понедельник\n”); case 2:printd(“вторник\n”); … case z:printd(“воскресенье \n”); } Выводит все дни до конца недели, начиная с указанного. Оператор Goto. Он есть, но совершенно не нужен и вообще от него один вред, потому что он нарушает принцип структурного программирования.

18.ЦИКЛЫ: ОРГАНИЗАЦИЯ ЦИКЛОВ FOR Цикл for - один из самых мощных (более часто используется, чем остальные). for(секция1; секция2; секция3) [ { тело_цикла }] Тело цикла – может быть одна инструкция, либо их может быть несколько (тогда они заключаются в фигурные скобки {} ). Секции 1,2,3 – содержат некоторые выражения. Чаще всего в них фигурирует переменная, называемая переменной цикла. Выражение1 один раз выполняется перед началом цикла. Перед каждой итерацией выполняется Секция2 (условие выполнения цикла). Если результат выполнения Секции2 равен нулю, то выполнение цикла прекращается. Секция3 выполняется после каждой итерации цикла. Она используется для приращения переменной цикла. Любая секция может отсутствовать, но обязательно должна присутствовать её ; . Тело цикла также может отсутствовать, но тогда в конце цикла ставится ; . void main() {for(;;);} /* Программа зацикливается, т.к. нету условия выхода из цикла*/ Если в секции находится несколько операторов, то они разделяются через запятую. ++i – инкремент переменной i в префиксной форме, i++ - в постфиксной форме. Постфиксная форма модифицирует переменную после выражения, в котором она встретилась, префиксная – до вычисления выражения. Для того, чтобы цикл for работал как обычный цикл с заданным числом повторений, нужно написать следующее: 1. for(i=1;i<10;i++) printf(“%d”,i); 2. for(i=1;i<10;printf(“%d”,i),i++); 3. for(i=1;i<10;printf(“%d”,i++)); В п.1-3 пример различного описания цикла for. Во всех 3х случаях на экран выводятся числа от 1 до 9.

19.ЦИКЛЫ WHILE И DO-WHILE while (условие) {тело_цикла; } Цикл выполняется пока условие не равно нулю. Тело структуры while может быть простым или составным оператором. При отсутствии в теле_цикла действия, которое в конечном счете приводит к тому, что условие в структуре while становится ложным, происходит «зацикливание». Пример цикла while: main() { int i; while(i<=1000) do i = i*2; } Цикл do/while: do {тело_цикла; } while (условие); Цикл выполняется пока условие не равно нулю. Отличается от предыдущего тем, что тело_цикла выполнится не менее одного раза. Структура do/while проверяет условие продолжения цикла после выполнения тела цикла. При наличии в теле цикла только одного оператора, нет необходимости использовать фигурные скобки.

20.УКАЗАТЕЛИ В СИ; НАЗНАЧЕНИЕ ТИПА УКАЗАТЕЛЯ В Си есть указатели. Указатель-переменная – это переменная, предназначенная для хранения адреса. Указатель-константа – значение адреса в оперативной памяти. Для работы с указателями в Си есть два оператора: & - взятие адреса объекта; * - взятие содержимого по адресу. &var1 – адрес переменной var1 (адрес её первого бита). * - возвращает значение найденное в памяти по указанному адресу. При описании переменной-указателя указывается тип данных, для доступа к которой используется указатель и * . Пример: int var1, *p1; /*var1 – переменная, p1 - указатель*/ p1 – имеет тип int * , т.е. говорят, что он ссылается на тип int. В выражениях: назначение * в описании переменных и выражениях различаются. Пример: int var1=10, *p1=(int*)600, *p2=&var1; print(“%d %d”,var1,*p2); * p2=20; print(“%d %d”,p2,var1); Эта часть программы выводит на экран: 10 10 20 20 Если не известно на какой тип данных ссылается указатель его можно объявлять как void *p . Константы в Си не имеют адреса, поэтому к ним не применимы операции взятия адреса и взятия содержимого по адресу. Указатели на указатели. Указатель в Си – обычная переменная, которая располагается по какому-то адресу. Можно взять этот адрес и присвоить другому указателю. Такие указатели называются указателями на указатели. При объявлении их указывается большее количество звёздочек. Пример: int var1=10, *p1,**p2,***p3; p1=&var1; p2=&p1, p3= &&&var1; printf(“%d %d %d”, *p1, **p2, ***p3); /*Выведет на экран: 10 10 10*/ В примере переменная p2 содержит в себе адрес ячейки памяти, в которой содержится адрес другой ячейки памяти, в которой содержится число 10.

21.ОПЕРАЦИИ НАД УКАЗАТЕЛЯМИ. АДРЕСНАЯ АРИФМЕТИКА Для указателей-переменных разрешены операции: 1) = 2)+ и – 3)++ и -- 4) = = = = (сравнение) – только для указателей одинакового типа, при этом на самом деле сравниваются адреса. При увеличении/уменьшении значения указателя физическое изменение значения зависит от его типа (от размера того объекта, на который указатель ссылается). Пример: Константа, добавленная к указателю, или вычитаемая из него, каждый раз автоматически умножается на размер соответствующего типа данных. int * p1 = (int * )10, * p2=p1+1; print(“%p %p”, p1, p2); /*На экране: 10 12*/ В Си существует специальный оператор sizeof() , возвращающий размер аргумента. Аргумент его – тип данных, либо переменная. С помощью этого оператора в момент выполнения программы можно узнать какой размер имеют типы данных. Например, для платформы DOS: sizeof(int)=2. Возвращаемый размер измеряется в байтах. sizeof() используется программистами, которые хотят чтобы их программа компилировалась и запускалась на любой аппаратной основе. При добавлении к указателю описанному как тип * константы N, его значение изменяется на N*sizeof(тип)

22.МАССИВЫ В СИ. СВЯЗЬ МЕЖДУ УКАЗАТЕЛЯМИ И МАССИВАМИ Для работы с массивами, активно используется адресная арифметика. С этой точки зрения * (p+2) отсчитывает третью ячейку памяти, начиная с адреса p. В результате с массивами можно работать и без специального типа данных. Чтобы не ставить лишних звёздочек, указатели поддерживают альтернативный синтаксис со смещением: []. p[2] или * (p+2) – имеют идентичный код. Благодаря этому, программисту кажется, что массивы в традиционном понимании в Си есть. Однако, на самом деле, эти массивы – просто последовательности значений в памяти и в виде собственных массивов существуют только в голове программиста. Указывая смещение, относительно начала массива (индекс элемента) программист должен сам заботиться, чтоб оно было осмысленным. Пример: int * p; printf(“%d”,p[-4]); В данном случае выводится пара байт, находящаяся в памяти перед началом предполагаемого массива.

23. ОДНОМЕРНЫЕ МАССИВЫ. РАЗМЕРНОСТЬ МАССИВА. ИНИЦИАЛИЗАЦИЯ МАССИВА Считается, что массивы в С есть. При объявлении массива пишется имя типа, имя массива и его размер в []. Пример: int a[10]; Имя массива является указателем-константой на нулевой элемент массива. Последним элементом массива из 10-ти элементов является элемент с номером 9. Это потому что первый элемент a[0]. При описании массива можно проинициализировать его элементы в фигурных скобках: int a[3]={1,2,3,’a’}; Элементов в фигурных скобках может быть меньше, чем зарезервировано размером массива. При такой инициализации размер в скобках можно не задавать: int a[]={‘1’,2,3,’a’}; В этом случае, размер массива определяется автоматически. Доступ к элементам массива производится по индексу в квадратных скобках, или по *. (cм. вопр. №22) Число байт, зарезервированных под массив можно узнать: sizeof(a); /*В данном случае 8 байт = 4элем*2 байта */

24. РАБОТА С МНОГОМЕРНЫМИ МАССИВАМИ В С бывают многомерные массивы, размерность массива – число индексов, используемых для ссылки на конкретный элемент. int x [10][10] двухмерная матрица int y [4][4][4][11] четырёх мерный массив. print а (“%d”,x[3][3]); - выводит на экран элементы находящиеся на пересечении 4-ой строки и 4-го столбца матрицы. Инициализация: int a[3][3]={11,12,13,21,22,23,31,32,33}; - самая левая размерность может отсутствовать и будет определяться по числу элементов в списке инициализации. char с[3][30]={“первая строка”,”вторая”,”третья”} Если нужно инициализировать не все элементы матрицы используются дополнительные фигурные скобки int a[3][3]={{11,12},{21,22,23},{31}}; Имя двумерного массива является указателем-константой на массив указателей констант. В этом массиве хранятся указатели-константы на начало каждой из строк матрицы int x[10][10]; x[9] – вернёт указатель-константу на последнюю строку матрицы x.

25. СВЯЗЬ МЕЖДУ ОДНОМЕРНЫМИ И МНОГОМЕРНЫМИ МАССИВАМИ. СПОСОБЫ ДОСТУПА К ЭЛЕМЕНТАМ МАССИВА Если имя одномерного массива – указатель-константа на элемент, то имя двумерного массива является указателем-константой на одномерный массив указателей-констант. Каждый элемент этого одномерного является указателем-константой на соответствующую строку матрицы. Для того чтобы работать с массивами активно используется адресная арифметика. С этой точки зрения *(p+2) отсчитывает третью ячейку памяти, начиная с адреса p. В результате с массивами можно работать и без специального типа данных. Чтобы не ставить лишних * указатели поддерживают альтернативный синтаксис со смещением b [ ] *(p+2) <=> p[2].

26. МАССИВЫ УКАЗАТЕЛЕЙ; УКАЗАТЕЛЬ НА УКАЗАТЕЛЬ Указатель в С – обычная переменная, которая располагается по какому-то адресу. Можно взять этот адрес и присвоить какому-то другому указателю. Такие указатели называются указателями на указатель. при объявлении их указывается большее количество * int var 1=10,*p1,**p2,***p3; p1=&var1; p2=&p1; p3=&&&var1; printf(“%d %d %d”,*p1,**p2,***p3); На экране: 10 10 10 Переменная px содержит в себе адрес ячейки памяти в которых содержится адрес другой ячейки памяти, в которой содержится число 10.

27. СТРОКОВЫЕ ДАННЫЕ. СТРОКИ И СИМВОЛЬНЫЕ МАССИВЫ; ИНИЦИАЛИЗАЦИЯ В С нет специального строкового типа. Для адресации строк используются указатели типа char, указывающие на начало сроки. Признаком конца строки является специальный символ обозначаемый ’\О’ и называемый нуль-терминатором. К строковым константам он добавляется автоматически: 'А' – 1 байт; “A” – 2 байта Строки можно хранить в массивах типа char char c[5]={“123”} '1' '2' '3' '\O' Строку можно объявить и проинициализировать как указатель char *c=”123” Если несколько указателей инициализируются одной и той же строковой константой, то при определённых настройках интегрируемой среды или компилятора может получиться так, что все они указывают на одну и ту же область памяти. Строки с '\O' на концах получили название ASCIIZ строки. В тех местах программы, где используется сроковые константы компилятор подставляет адрес нулевого символа этой константы, это значит что в результате компиляции вместо строковых констант подставляется char* char a[80] scanf (“%s”,a); printf (“%s”,a); ввод строки с клавиатуры char a[80] gets (a) printf (“%s”,a);

28.ФУНКЦИИ ОБРАБОТКИ СТРОК: КОПИРОВАНИЕ ДАННЫХ СТРОКИ копирование данных строки Прототип Описание функции char *strcpy(char *dst, const char *src) Копирует строку src в массив dst. Возвращает значение dst. char *strncpy(char *dst, const char *src, size_t n) Копирует не более чем n символов строки src в массив dst. Возвращает dst. Более безопасный вариант по сравнению с strcpy, так как гарантирует, что копия строки «не вылезет» за границы выделенной памяти. char *strdup(char *src) Выделяет память и копирует в нее содержимое строки src. Возвращает указатель на начало строки копии или константу NULL в случае, если память выделить не удалось. Примечание 1. Указатель dst обязательно должен указывать на предварительно выделенную область памяти. В противном случае возможно модификация (изменение, удаление) данных в оперативной памяти – происходит «затирание» одной информации другой. Примечание 2. Тип size_t является беззнаковым целым, то есть typedef unsigned int size_t. Примечание 3. Функции возможно использовать только после подключения библиотеки string.h.

29.ФУНКЦИИ ОБРАБОТКИ СТРОК: ИЗМЕНЕНИЕ СТРОК. Прототип Описание функции char *strrev(char *s) Меняет порядок символов в строке s на обратный. char *strupr(char *s) Все символы строки s приводятся к верхнему регистру. Применяется только для букв латинского алфавита. char *strlwr(char *s) Все символы строки s приводятся к нижнему регистру. Применяется только для букв латинского алфавита. char *strcat(char *dst, const char *src) Объединяет строку src со строкой массива dst. Первый символ src переписывает символ NULL строки dst. Возвращает значение dst. char *strncat(char *dst, const char *src, size_t n) Объединяет не более чем n символов строки src со строкой массива dst. Первый символ src переписывает символ NULL строки dst. Возвращает значение dst. char *strset(char *dst, int ch) Заполняет все позиции строки dst символом ch. char *strnset(char *dst, int ch, size_t n) Заполняет не более чем n позиций строки dst символом ch. Примечание 1. Тип size_t является беззнаковым целым, то есть typedef unsigned int size_t. Примечание 2. Функции возможно использовать только после подключения библиотеки string.h.

30. ФУНКЦИИ ОБРАБОТКИ СТРОК: СРАВНЕНИЕ СТРОК Прототип Описание функции int strcmp(const char *s1, const char *s2) Сравнивает строку s1 со строкой s2. Функция возвращает 0, значение меньше 0 или больше 0, если s1 соответственно равна, меньше или больше s2. Сравнение осуществляется лексикографическое с учетом регистра. int stricmp(const char *s1, const char *s2) Аналогично функции strcmp за исключением того, что сравнение осуществляется без учета регистра. int strncmp(const char *s1, const char *s2, size_t n) Сравнивает до n символов строки s1 со строкой s2. Функция возвращает 0, значение меньше 0 или больше 0, если s1 соответственно равна, меньше или больше s2. Сравнение осуществляется лексикографическое с учетом регистра. Примечание 1. Тип size_t является беззнаковым целым, то есть typedef unsigned int size_t. Примечание 2. Функции возможно использовать только после подключения библиотеки string.h. Примечание 3. Корректное сравнение возможно только для строк, содержащих буквы латинского алфавита.

31. ФУНКЦИИ ОБРАБОТКИ СТРОК: ПОИСК В СТРОКЕ Прототип Описание функции int strlen(const char *s) Определяет длину строки s. Возвращает число символов, предшествующих ограничивающему символу NULL. char *strchr(const char *s, int c) Находит позицию первого вхождения символа c в строке s. Если c найден, функция возвращает указатель на c в строке s. В противном случае возвращается указатель со значением NULL. char *strrchr(const char *s, int c) Находит позицию последнего вхождения символа c в строке s. Если c найден, функция возвращает указатель на c в строке s. В противном случае возвращается указатель со значением NULL. char *strstr(const char *s1, const char *s2) Находит позицию первого вхождения строки s2 в строку s1. Если подстрока найдена, возвращает указатель подстроки в строке s1. В противном случае возвращается указатель со значением NULL. char *strpbrk(const char *s1, const char *s2) Находит в строке s1 позицию первого вхождения любого из символов строки s2. Если символ из строки s2 найден, функция возвращает указатель на этот символ в строке s1. В противном случае возвращается указатель со значением NULL. Используется для поиска разделителей в строке. char *strtok(char *s1, const char *s2) Последовательный вызов функции выполняет разбиение строки s1 на лексемы (логические части, такие как слова в текстовой строке), разделенные символами, содержащимися в строке s2. При первом вызове функция получает в качестве аргумента строку s1, а в последующих вызовах, чтобы продолжить разбиение той же самой строки, в качестве первого аргумента передается NULL. При каждом вызове возвращается указатель на текущую лексему строки s1. Если при очередном вызове функция находит, что лексем в строке не осталось, то возвращается NULL. Примечание 1. Функции возможно использовать только после подключения библиотеки string.h.

32. ФУНКЦИИ ОБРАБОТКИ СТРОК: СРЕДСТВА ПРЕОБРАЗОВАНИЯ ЧИСЛОВЫХ ДАННЫХ В СТРОКИ И ОБРАТНО Прототип Описание функции double atof(const char *s) Преобразует строку s в тип double. int atoi(const char *s) Преобразует строку s в тип int. long atol(const char *s) Преобразует строку s в тип long. char *itoa(int value, char *string, int base) Преобразует число value типа int в строку string по основанию base (система счисления). char *ltoa(long value, char *string, int base) Преобразует число value типа long в строку string по основанию base (система счисления). char * gcvt(double value, int n, char *string) Преобразует первые n цифр числа value типа double в строку string. Примечание 1. Функции возможно использовать только после подключения библиотеки stdlib.h. Примечание 2. Если преобразование строки в число невозможно, то поведение функций atof, atoi, atol не определено.

33. ФУНКЦИИ РАБОТЫ С СИМВОЛЬНЫМИ ДАННЫМИ (CTYPE.H) Прототип Описание функции int isdigit(int c) Возвращает значение 1, если с является цифрой, и 0 в других случаях. int isalpha(int c) Возвращает значение 1, если с является буквой, и 0 в других случаях. int islower(int c) Возвращает значение 1, если с является буквой нижнего регистра, и 0 в других случаях. int isupper(int c) Возвращает значение 1, если с является буквой верхнего регистра, и 0 в других случаях. int tolower(int c) Если с является буквой верхнего регистра, то tolower возвращает с как букву нижнего регистра. В других случаях tolower возвращает аргумент без изменений. int toupper(int c) Если с является буквой нижнего регистра, то toupper возвращает с как букву нижнего регистра. В других случаях toupper возвращает аргумент без изменений. int isprint(int c) Возвращает значение 1, если с является отображаемым при печати символом, включая символ пробела, и 0 в других случаях. Примечание 1. Функции возможно использовать только после подключения библиотеки ctype.h.

34. СТРУКТУРЫ. ДОСТУП К ЭЛЕМЕНТАМ; РАЗМЕЩЕНИЕ В ПАМЯТИ Наиболее близкими типами данных в Pascale являются записи. Синтаксис: struct имя_типа { список полей; }; Имя типа может отсутствовать если сразу за закрывающейся фигурной скобкой указаны имена переменных, например struct { int a; char b; } var1; При объявлении переменных структурного типа перед именем типа ставится слово struct int { struct ffblk var1; Доступ к полям структуры осуществляется с помощью оператора . (точка) имя_стр . член Пример struct student { char fio[30]; int zach; int kurs; } vika; strcpy (vika.fio,”Чашук В.И.”); vika.zach = 2689 vika.kurs = 3 printf (“%s %d %d”, vika.fio,vika.zach,vika.kurs);

1...2

bbb
bb1
bb2
bb3
1

На главную

1
1

вверх

2
Используются технологии uCoz