Int * slmas(int k, int a[], int l, int b[])
{int *c=new int [k+l];
int i=0,j=0,m=0;
while (i<k &&j<l)
if (a[i]<b[j]) c[m++]=a[i++];
else c[m++]=b[j++];
while (i<k) c[m++]=a[i++];
while (j<l) c[m++]=b[j++];
return c;
}
Здесь с – либо указатель на динамический массив, либо с- указатель на глобальный массив.
Лекция 7.3
Дополнение к предыдущей лекции
Память под динамический массив должна освобождаться. Для этого используется операция delete:
Для переменной: delete u;
Для массива: delete [] p;
Дин. память освобождается автоматически после окончания работы программы. Освобождение памяти , когда она больше не нужна, является хорошим тоном, а иногда это требуется выполнить обязательно. Однако , если в функции описана локальная переменная- указатель и ей присвоено значение по new , то по окончании работы функции эта переменная- указатель исчезнет, а выделенная дин. память останется недоступной.
Структуры
Структура – совокупность фиксированного количества данных, необязательно однотипных, упорядоченных способом перечисления:
Тип1 элемент1;
Тип2 элемент2;
. . . . . . . . .
ТипN элементN;
Описание структуры
struct [имя]
{ Тип1 элемент1; //элементы структуры
Тип2 элемент2; //называются полями.
. . . . . . . . .
ТипN элементN;
}[список описателей переменных,указателей,
массивов];
Это описание задаёт тип , имя этого типа указывается в заголовке, но можно не давать имя этому типу, а просто описать имена переменных этого типа после описания тела структуры.
Пример:
struct Point
{double x,y;} M1,M2; // M1,M2- переменные типа Point
Можно и так:
struct
{double x,y;}
M1,M2,*p,q[15]; // M1,M2- того же типа, но имени у типа нет.
struct Point
{double x, y;};
Использование имени структуры:
==для описания переменных типа структуры;
Point a,b;
Point t[10]; массив из 10 точек;
==для описания указателей на структуру;
Point * p;
Point * p=&a;
Возможна инициализация структуры: в этом случае значения элементов указываются в порядке расположения элементов в описании структуры.
struct vec
{int n;
double a[10];
};
vec v={5,{1,1,1,1,1}}; //инициализация v
Под переменную типа структуры отводится место в оперативной памяти, где последовательно располагаются элементы в порядке описания.
v:
n=5 a[0]=1 a[1]=1 a[2]=1 a[3]=1 a[4]=1 a5 a6 a7 a8 a9
Доступ к полям структуры выполняется с помощью операций выбора: (точка),если доступ выполняется через имя структуры или(->)при доступе через указатель:
имя_структуры. имя_поля –это составная переменная, тип её как у поля, например: M1.x , M1.y , t[2].x, t[2].y
или при Point * p;
имя указателя -> имя поля ,например, p->x , p->y – тоже сост. переменная типа того же, как у поля.
Доступ возможен и такой (*p).x или (*p).y
Использование переменных – структур:
==переменной типа структура можно присвоить переменную того же типа;
М1=М2; // выполняется поэлементное копирование
==структуру можно передавать в функцию через аппарат формальных/ фактических параметров по значению или по адресу;
double R(Point a,Point b)
{double u=a.x-b.x,v=a.y-b.y;
return sqrt(u*u+v*v);}
Вызов функции cout<<R(M1,M2);
==функция может возвращать результат типа структура, типа указатель на структуру.
==Ввод структур с клавиатуры, вывод структур на экран выполняются поэлементно на уровне элементов простого типа.
Например, cin>> M1.x>> M1.y;
cin>>v.a[i];
cout<<t[i].x<< t[i].y;
cout<< p->x<< p->y;
== элементом структуры может быть другая структура, указатель на ту же или другую структуру.
Struct krug // структура круг
{Point a; // центр
double r; // радиус
};
krug z;
Доступ к координатам центра: z.a.x , z.a.y и радиусу: z.r
krug *t=&z; t->a.x t->r t->a.y //слева направо (t->a).x
Строки.
Строка – это конечная последовательность символов, т.е. естественно рассматривать строку как последовательность символов. Однако строковая переменная отличается от обыкновенного массива тем, что в конце строкового значения записывается специальный символ '\0’, означающий конец строки. Его называют нуль-символом.
Описание строки:
char имя [размер_строки]; //размер учитывает и нуль-символ
Рекомендуется:
сonst int ds=80; =описать константу, равную максимальной длине строки.
=описать строку.
char имя_строки [ds+1];
Инициализация строки:
char s[7]="ABCDEF";
char u[]="ABCDEF"; //как и выше s[7]
char *v="ABCDEF"; //
cout<<s<<'\n'; //ABCDEF
cout<<u<<'\n'; //ABCDEF
cout<<v<<'\n'; //ABCDEF
char w[3]={'A','B','C'}; //здесь символ ‘\0’ не ставится
cout<<w<<'\n'; //ABCxxxxxxxxxx
имя строки – константный указатель на строку.
Строковую переменную отличает от массива символ ‘\0’ в конце строки. Отличие – в способе использования массива символов.
Доступ к символу строки, как и к элементу массива: переменная с индексами s[0] ,s[1],. . .s[6] –эти переменные типа char.
!!!Нельзя :
==присвоить одной строке другую строку с помощью операции =, но можно организовать цикл и в нем поэлементное присваивание ;
!!!Нельзя :
==сравнивать две строки с помощью операции ==;
В С++ есть две возможности:
~~функции, унаследованные из С (подключить заголовочный файл cstring);
~~использовать библиотечный класс С++ string, который представляет широкие возможности представления, обработки и контроля строк (это во 2-м семестре).
Пример функции копирования строк
char * strcpy(char * s1, char * s2) –копирует строку s2 в s1, возвращает s1, это возвращение бывает нужно, если вызов этой функции используется , как аргумент при обращении к другой функции.
char * strncpy(char * s1, char * s2) –копирует первые n символов из s2 в s1, возвращает s1.
Ввод – вывод строк
Строки можно выводить с помощью операции<<:
cout<<s<<”-cумма\n”;
В строковые переменные можно вводить значения с помощью операции >>: cin>>s; - при вводе все пробелы и символы КС до строкового значения игнорируются, кроме того есть особенность ввода строк- ввод строки завершается, если встретился пробел или символ КС, т.е. ввод предложения с пробелами между словами не возможен этим способом.
char s[100],t[50];
cin>>s; // поток: ” abc efg “
cin>>t;
cout<<s<<t; // выведется: “abcefg”
==функция для ввода строки: getline(s,num,lim=’\n’) -считывает num-1 символ(или пока не встретится символ lim),копирует считанные символы и символ lim тоже.
Пример: вводится строка s и копируется в другую строку d.
char s[80],d[80];
cin.getline(s,80);
1 вариант: int l= strlen(s); for (int i=0;i<=l; ++i) d[i]=s[i];
Более эффективно не вычислять длину строки s, а выполнять проверку на нуль-символ непосредственно в цикле:
2 вариант: for(int i=0;s[i]!=0;++i)d[i]=s[i]; d[i]=0;
for(int i=0; s[i]; ++i) d[i]=s[i]; d[i]=0;