
- •Простые типы данных
- •Модификаторы
- •1. Запись целых констант
- •2. Запись вещественных констант
- •3. Запись символьных констант
- •1. Арифметические операции над данными целочисленных типов
- •Простые типы данных
- •Модификаторы
- •Операция присваивания
- •Простые типы данных
- •Модификаторы
- •Операция присваивания
- •Диапазоны значений простых типов данных для ibm pc
- •5. Структура программы. Функции.
- •2. Формальные параметры функций
- •3. Возвращаемые значения функций
- •2.2 Пример простой программы на языке Си.
- •Управляющие конструкции
- •Ветвления
- •Циклы while, do.. .While и for
- •Теоретичсекий зачет по операторам цикла
- •Графика
- •Указатели
- •Преобразование типов
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Задание:
- •Операции над указателями.
- •Структуры
- •Объединения
- •. Описания типов (typedef)
- •Поразрядные операции (bitwize)
Графика
#include<conio.h>
#include<graphics.h>
#include<stdlib.h>
#include<stdio.h>
int gd,gm;
int gd=DETECT,gm;
main()
{
initgraph(&gd,&gm,"..\\bgi");
setcolor(5);
settextstyle(DEFAULT_FONT,HORIZ_DIR,5);
outtextxy(20,20,"ПРОБА ");
closegraph;
}
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
int gd=DETECT,gm;
main()
{
initgraph(&gd,&gm,"..\\bgi");
setcolor(6);
settextstyle(GOTHIC_FONT,0,12);
outtextxy(100,100,"proba");
setcolor(2);
line(0,0,100,100);
putpixel(200,200,1);
getch();
closegraph;
}
Построение графиков
. Пользуясь графическими командами, мы можем нарисовать очень ограниченный набор линий. Более сложные задачи, например, моделирование движения по сложным траекториям, требует построения линий из точек. Один из способов решения этой задачи известен вам из алгебры - построение графиков функций. Давайте попробуем такую программу разработать.
Значение x будет меняться от края до края экрана, а значение y вычисляться по заданной формуле.
Для того, чтобы графики "знакомых" функций выглядели привычно, нужно выбрать более удобную систему координат. Начало координат поместим в центр экрана, а оси направим, как обычно, Ox - влево, а Oy - вверх. Изобразим их на экране (для простоты ограничимся лишь прямыми линиями, не изображая стрелок и надписей).
SetColor(Green);
Line(0,240,639,240); ось Ox
Line(320,0,320,479); ось Oy
Начнем строить график. Теперь нам придется иметь дело с двумя системами координат - "экранной" и "нарисованной". Вычислять значение функции нам удобнее в нарисованной системе, а рисовать точки придется в экранной. Обозначим через x и y координаты точки в нарисованной системе, а x_ekr и y_ekr - в экранной. Связь между ними будет такой:
x_ekr = x - 320 y_ekr = -y + 240
Из этих соотношений видно, что когда x_ekr меняется от 0 до 639 (от левого до правого края экрана), x меняется от -320 до +319, а при изменении y_ekr от 0 до 479 (от верхнего края до нижнего) y меняется от +240 до -239 (т.е. в обратном направлении).
Пользуясь этими соотношениями, составим новую программу построения графика:
#include<stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
int gd=DETECT,gr;
main()
{initgraph(&gd,&gr,"..\\bgi");
float x,y,xg,yg,a,i;
a=0;
x=-20;
for (i=0;i<2000;i++)
{y=sin(x);
xg=x*20+320;
yg=240-y*20;
putpixel(xg,yg,2);
x=x+0.05;
}
getch();
closegraph;
}
Программа- заставка из зачета по графике
#include<stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
int gd=DETECT,gr;
main()
{initgraph(&gd,&gr,"..\\bgi");
int x,y,xg,yg,a,i;
i=0;
for (y=50;y<620;y++)
{
setcolor(1);
settextstyle(3,0,i);
outtextxy(y,50,"VASYA");
delay(10);
setcolor(0);
outtextxy(y,50,"VASYA");
delay(10);
if (y%10==0) i++;
}
getch();
closegraph;
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><!-- saved from url=(0043)http://www.edu.severodvinsk.ru/book/c/9.htm --><!-- saved from url=(0047)http://archive.1september.ru/inf/2000/6/C/9.htm -->
Строки
Описание строк и примеры строковых функции
Строки есть массивы типа char, оканчивающиеся спецсимволом \0
char string[20];
string[0] = 'П';
string[1] = 'р';
string[2] = 'и';
string[3] = 'в';
string[4] = 'е';
string[5] = 'т';
string[6] = '\0';
printf("%s\n", string);
%s - формат для печати СТРОК.
ПОЧЕМУ ДЛЯ СТРОК ИЗОБРЕЛИ СИМВОЛ "ПРИЗНАК КОНЦА"?
Строка - это ЧАСТЬ массива букв.
В разное время число букв в строке может быть различным, лишь бы не превышало размер массива (тогда случится сбой программы). Значит, следует где-то хранить текущую длину строки (число использованных
символов). Есть три решения:
В отдельной переменной. Ее следует передавать во все
функции обработки данной строки (причем она может изменяться).
char str[32]; /* массив для строки */
int slen; /* брать первые slen букв в этом массиве */
...
func(str, &slen); /* ДВА аргумента для передачи ОДНОЙ строки */
...
Этот подход работоспособен, но строка разбивается на два
объекта: сам массив и переменную для его длины. Неудобно.
(2) Хранить текущую длину в элементе str[0],
а буквы - в str[1] ... итд.
Плохо тем, что в str[0] можно хранить лишь числа от 0 до 255,
и если строка длиннее - то такой подход неприменим.
(3) Не хранить длину НИГДЕ, а ввести символ-признак конца строки.
Теперь в
func(str); /* ОДИН аргумент - сам массив */
передается только сам массив, а его текущая длина может быть
при нужде вычислена при помощи некоей функции, вроде такой:
int strlen(char s[]){ /* функция от массива букв */
int counter = 0; /* счетчик и одновременно индекс */
while(s[counter] != '\0') /* пока не встретился признак конца текста */
counter++; /* посчитать символ */
return counter; /* сколько символов, отличных от '\0' */
}
Тут никаких ограничений нет. Именно этот подход и был избран
в языке Си, хотя в принципе можно самому пользоваться и другими.
Строки будем описывать и работать с ними, как с массивами символов.
Примеры описаний:
<SPAN lang=EN-US style="mso-ansi-language: EN-US"> char s[10]; char s[10]="123"; char</SPAN> *s:="123"; <SPAN lang=EN-US style="mso-ansi-language: EN-US"> char *s={</SPAN>'1','2','3','<SPAN lang=EN-US style="mso-ansi-language: EN-US">\0</SPAN>'}; <SPAN lang=EN-US style="mso-ansi-language: EN-US"> char *s={</SPAN>'1','2','3',0}; <SPAN lang=EN-US style="mso-ansi-language: EN-US"> char *s=</SPAN>{'1','2','3'};
В первом случае просто описывается символьный массив из десяти элементов. Надо иметь в виду, что если мы собираемся использовать его как строку, то реально мы сможем использовать лишь девять символов, а еще один нам понадобится для "нулевого" символа, ограничивающего строку.
Во втором случае описывается символьный массив из десяти элементов (т.е. в памяти выделяется 10 байт), но инициализирующая строка содержит четыре символа (а максимум может содержать девять ? опять не следует забывать о нулевом!). Значения остальных элементов массива не определены (но память под них выделена).
Третий пример отличается от второго тем, что в памяти выделяется ровно четыре байта под строку s, Обратиться к s [3] мы еще можем (это символ ' \0' ), а вот запись s [4 ] , хотя у компилятора к ней не будет претензий, уже неверна. Нет у строки s такого элемента!
Четвертый и пятый примеры полностью эквивалентны третьему, отличаются они лишь тем, как записан символ с кодом 0. Но это совершенно безразлично.
А вот в шестом примере строка не описывается вовсе, потому что у нее нет завершающего нулевого символа. Можно считать, что мы просто описываем и инициализируем символьный массив из трех элементов. Если мы захотим обращаться с s как со строкой, то в нашем распоряжении будут всего два элемента (один мы должны будем "отдать" под признак конца строки).
Отметим, что присваивать значение строке целиком можно только при инициализации в описании (как и в случае с массивами). Так, как показано ниже, делать нельзя: <SPAN lang=EN-US style="mso-ansi-language: EN-US">unsigned char s[10]; s="123" или <SPAN lang=EN-US style="mso-ansi-language: EN-US">unsigned char *s; </SPAN><SPAN lang=EN-US>s="123";</SPAN></SPAN>
Функции работы со строками <string.h>
Имеются 2 группы функций, работающих со строками, они определяются в <String.h>. Имена функций первой группы начинаются с str, второй с mem. Функции сравнения рассматривают аргументы как массивы элементов типа unsigned char.
В таблице переменные s и t имеют тип char*, сs и st -const char*, n-size_t, а c- значение типа int, приведенное к char.
Последовательные вызовы strtok разбивают строку s на лексемы. Ограничителем лексемы служит любой символ из строки st. В первом вызове указатель s не равен NULL. Функция находит в строке s первую лексему, состоящую из символов, не входящтх в st, ее работа заканчивается тем, что поверх следующего символа пишется '\0' и возвращается указатель на лексему. Каждый последующий вызоу, в котором указатель s равен NULL, возвращает указатель на следующую лексему, которую функция будет искать сразу за концом предыдущей. Функция strtok возвращает NULL, если далее никакой лексемы не обнаружено. Параметр st от вызова к вызову может варьироваться.
strcpy(s,ct) |
копирует строку ct в строку s, включая '\0', возвращает s |
strncpy(s,ct,n) |
копирует не более n символов строки ct в строку s, возвращает s. Дополняет результат символами '\0', если символов в ct меньше n |
strcat(s,ct) |
приписывает ct к s. возвращает s |
strncat(s,ct,n) |
приписывает не более n стмволов ct к s, завершая s стмволом '\0', возвращает s |
strcmp(cs,ct) |
сравнивает cs и ct. возвращает <0, если cs<ct, 0 если равны, и >0, если cs>ct. сравнение лексикографическое, те cs<ct, если первый несовпавший символ в cs арифметически меньше соответствующего стмвола из ct |
strncmp(cs,ct) |
сравнивает не более n символов cs и ct. возвращает <0, если cs<ct, 0 если равны, и >0, если cs>ct. сравнение лексикографическое, те cs<ct, если первый несовпавший символ в cs арифметически меньше соответствующего стмвола из ct |
strchr(cs,c) |
возвращает указатель на первое вхождение c в cs, елси такогвого не оказалось, NULL |
strrchr(cs,c) |
возвращает указатель на последнее вхождение c в cs, елси такогвого не оказалось, NULL |
strspn(cs,ct) |
возвращает длину начального сегмента cs, состоящего из символов, входящих в строку ct |
strcspn(cs,ct) |
возвращает длину начального сегмента cs, состоящего из символов, не входящих в строку ct |
strpbrk(cs,ct) |
возвращает указатель в cs на первый символ, который совпал с одним из символов, входящих в ctили NULL |
strstr(cs,ct) |
возвращает указатель в cs на первое вхождение ct в cs или NULL |
strlen(cs) |
длина строки |
strerror(n) |
возвращает указатель на зависящую от реализвации строку, соотв. номеру ошибки n |
strtok(s,ct) |
ищет в s лексему, ограниченную символами из ct |
Функции mem предназначены для манипулирования с объектами как с массивами символов, их назначение - получить интерфейсы к эффективным программам. В таблице s и t имеют тип void*, Cs и ct-const void*. n-size_t,c-int приведенное к char
memcpy(s,ct,n) |
копирует n символов из ct в d и возвращает s |
memmove(s,ct,n) |
копирует n символов из ct в d и возвращает s, к тому же работает в лучае "перекрывающихся объектов" |
memcmp(cs,ct,n) |
сравнивает первые n символов cs и ct, резтат тот же, что strcmp |
memchr(cs,c,n) |
возвращает указатель на первое вхождение символа c в cs или, если среди первых n символов c не встретилось, то NULL |
memset(s,c,n) |
размещает символ c в первых n похициях строки s и возвращает s |
Задание на строки:
1. Ввести 3 строки: str1 (с помощью scanf) str2 (с помощью gets) и str3="Вася"/
определить длину каждой строки и вывести
слить 3 строки (через пробелы) в предложение и поместить в строку Str4. Вывести саму строку и ее длину
скопировать в новую строку str5 первый слог строки str3 5 раз. Вывести и определить длину получившейся строки
определить длину начального сегмента строки str3, входящего в строку str5
2. Задание на массивы:
определить в одномерном массиве три чисал, стоящие подряд, сумма которых максимальна.
определить и вывести на экран в двумерном массиве столбеб, сумма элементов которого минимальна
если в двумерном массиве етсь отрицательное число, то заменить всю строку с этим числом на 0
#include <string.h>
#include <stdio.h>
#include <conio.h>
main()
{
char name[15], soname[25], s1[20], s2[30],s3[10];
char u;
clrscr();
int i,k;
printf ("введите первую строку\n");
scanf("%s", name);
k=strlen(name);
printf("длина первой строки %d\n", k);
printf ("введите вторую строку\n");
scanf("%s", soname);
printf ("привет, %s %s\n", name, soname);
strcpy(s1,"это");
strcat(s1, soname);
printf("слияние строк %s\n", s1);
strcpy(s1," Вас");
i=strcmp( name,s1);
if (i==0) strcpy(s2,"строки равны");
else
if (i>0) strcpy(s2,"первая больше второй");
else strcpy(s2,"вторая больше первой");
printf("результат сравнения строк %s\n", s2);
strncpy(s3,soname,2);
printf("копирование n символов строки %s \n",s3);
i=strspn(name,s1);
printf("длина нач. сегмента name, сост. из символов входящих в s1 %d\n",i);
i=strcspn(name,s1);
printf("длина нач. сегмента name, сост. из символов не входящих в s1 %d\n",i);
}