Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование ответы.docx
Скачиваний:
58
Добавлен:
30.01.2018
Размер:
407.05 Кб
Скачать

Функция strcmp(str1, str2).

После сравнения строк str1 и str2 данная функция возвратит целое значение:

  • <0 , если

  • =0 , если

  • >0 , если

Эта функция производит сравнение, различая прописные и строчные буквы

Пример:

#include "stdafx.h"

#include <iostream>

#include <cstring>

using namespace std;

int main()

{

setlocale(LC_ALL,"RUS");

char s1[]="Hello";

char s2[]="Helloll";

int k=strcmp(s1,s2);

cout<< k; //выведет -1 т.к. 1 строка<2 строки

system ("pause");

return 0;

}

Функция stricmp.

Функция stricmp имеет тот же прототип как и функция strcmp. Отличие этих двух функций лишь в том, что stricmp не различает регистр символов. Т.е. для предыдущего примера на экран выведется 0.

Функция strncmp.

Эта функция сравнивает num первых символов строк, на которые указывают указатели str1 и str2. Пример:

#include "stdafx.h"

#include <iostream>

#include <cstring>

using namespace std;

int main()

{

setlocale(LC_ALL,"RUS");

char s1[]="Hello";

char s2[]="HeLlo";

int k=strncmp(s1,s2, 2);

cout<< k; //выведет 0 т.к. вторые символы не различаются

system ("pause");

return 0;

}

Функция strnicmp. Сравнивает первые num символов без учета регистра.

  1. Понятие указателя. Способы инициализации указателей. Операции с указателями. Привести примеры работы с указателями на языке С/C++.

Указатель – переменная, значением которой является адрес ячейки памяти. То есть указатель ссылается на блок данных  из области памяти, причём на самое его начало. Указатель может ссылаться на переменную или функцию. Для этого нужно знать адрес переменной или функции.

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

float r, b; float *ukr = &r, *ukb = &b;

В таком описании указателей с инициализацией ничего странного нет, ибо &r и &b являются константами типа указатель.

Второй способ:присвоить указателю значение другого указателя, к этому моменту уже правильно инициализированного, например:

char *uk_simv_rus, *uk_simv_lat; char simvsmoll, simvlarge;  . . . . . . . . .  uk_simv_lat = &simvsmoll;  uk_simv_rus = uk_simv_lat;

Обратим внимание на то, что в этом случае разные указатели содержат адреса одной и той же переменной. Значит, к переменной simvsmoll можно обратиться как через указатель uk_simv_rus так и через указатель uk_simv_lat, что зачастую предоставляет программисту дополнительные удобства.

#include <cstring>

#include <iostream>

using namespace std;

int main()

{

int var = 123; // инициализация переменной var числом 123

int *ptrvar = &var; // указатель на переменную var (присвоили адрес переменной указателю)

cout << "&var = " << &var << endl;// адрес переменной var содержащийся в памяти, извлечённый операцией взятия адреса

cout << "ptrvar = " << ptrvar << endl;// адрес переменной var, является значением указателя ptrvar

cout << "var = " << var << endl; // значение в переменной var

cout << "*ptrvar = " << *ptrvar << endl; // вывод значения содержащегося в переменной var через указатель, операцией разименования указателя

system("pause");

return 0;

}

Третий способ:использовать одну из встроенных функции распределения памяти, например, malloc. Обращение к функции malloc имеет вид: malloc(<размер>);

Функция malloc выделяет (резервирует) из области “куча” (heap) память длиной <размер>байтов, где <размер> задается выражением типа unsigned. Функция возвращает адрес выделенной памяти в виде константы-указателя типа void.

Инициализацию указателя можно осуществить следующим образом:

int *x = (int *)malloc(sizeof(int));

  1. Указатели и массивы. Методы ссылки на элементы массива. Привести примеры программ с использованием ссылок на языке С/C++.

В языке СИ между указателями и массивами существует тесная связь. Например, когда объявляется массив в виде int array[25], то этим определяется не только выделение памяти для двадцати пяти элементов массива, но и для указателя с именем array, значение которого равно адресу первого по счету (нулевого) элемента массива, т.е. сам массив остается безымянным, а доступ к элементам массива осуществляется через указатель с именем array. Поскольку имя массива является указателем допустимо, например, такое присваивание:

int array [25];

int *ptr;

ptr=array;

Здесь указатель ptr устанавливается на адрес первого элемента масcива.

Для доступа к элементам массива существует два различных способа. Первый способ связан с использованием обычных индексных выражений в квадратных скобках, например, array[16]=3.

Второй способ доступа к элементам массива связан с использованием адресных выражений и операции разадресации в форме *(array+16)=3. При таком способе доступа адресное выражение равное адресу шестнадцатого элемента массива тоже может быть записано разными способами *(array+16) или *(16+array).

Для доступа к начальному элементу массива (т.е. к элементу с нулевым индексом) можно использовать просто значение указателя array или ptr. Любое из присваиваний присваивает начальному элементу массива значение 2.

*array = 2;

array[0] = 2;

*ptr = 2;

ptr[0] = 2;

Пример программы с использованием ссылок на языке С/C++

#include "stdafx.h"

#include <iostream>

using namespace std;

 

int main(int argc, char* argv[])

{

    int value = 15;

    int &reference = value; // объявление и инициализация ссылки значением переменной value

    cout << "value     = " << value     << endl;

    cout << "reference = " << reference << endl;

    reference+=15; // изменяем значение переменной value посредством изменения значения в ссылке

    cout << "value     = " << value     << endl; // смотрим, что получилось, как будет видно дальше значение поменялось как в ссылке,

    cout << "reference = " << reference << endl; //  так и в ссылочной переменной

    system("pause");

    return 0;

}

  1. Передача массивов в качестве параметров в функцию. Привести пример передачи массива вещественных чисел в функцию, вычисляющую сумму его элементов.

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

Вычисление суммы элементов массива вещественных чисел

#include <cstring>

#include <iostream>

using namespace std;

double summa (double array[], int n)

{

double s=0;

for(int i=0;i<n;i++)

{s+=array[i];}

return s;

}

int main()

{

double v[10]={1,2,3,4,5,6,7,8,1,5};

cout<<summa(v,10)<<endl;// весь массив

cout<<summa(v+5,5)<<endl; //последние 5 элэментов

system("pause");

return 0;

}

  1. Статическое и динамическое выделение памяти. Операторы new и delete.

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

Основное различие этих методов: эффективность и гибкость. Статическое более эффективно, т.к. выделение памяти происходит до выполнения программы, но оно менее гибко, т.к. нужно заранее знать тип и размер размещаемого объекта.

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

Динамические объекты не имеют собственного имени и действия над ними производятся косвенно (с помощью указателей)

-Выделение и освобождение памяти под статические объекты делает компилятор автоматически.

-Выделение и освобождение памяти под динамические объекты возлагается на программиста. Для манипуляции динамически выделяемой памятью служат операторы deleteиnew.

Newимеет 2 формы: 1. Выделяет память под единичный объект определенного типа:

Int*pint=newint(1024);

2. выделяет память под массив заданного размера, состоящий из элементов определенного типа:

Int*pia=newint[4];

Удаление динамического объекта, который больше не нужен, чтобы освободить память:

-освобождение единичного объекта: deletepint;

-освобождение массива: delete[ ] pia;

  1. Статические и динамические массивы: объявление, инициализация, использование. Привести примеры создания и обработки статического и динамического массивов на языке С/C++.

Статические массивы как и другие статические типы данных это объекты размер которых известен на этапе компиляции. Такие массивы существуют всё время жизни программы. Размер их неизменен. Данные в них изменять можно.Динамический массив– это массив, размер которого заранее не фиксирован и может меняться во время исполнения программы. Динамические массивы дают возможность более гибкой работы с данными, так как позволяют регулировать размер массива в соответствии с реально необходимыми объемами.

Объявление и инициализация: статического массива:

тип_элемента имя_массива[количество_элементов]={необязательные исходные значения}

Динамического массива:

<тип данных> *<имя массива> = new <тип переменных> [<количество ячеек>];

<количество ячеек> — здесь мы задаем размер массива (например [n] или [25]).

Пример создания и обработки статического массива:

#include <iostream>

using namespace std;

int main(){

int Arr[3] = {1,2,3}; //Инициализация массива набором значений

cout << Arr[0] << '\n'; //Вывод элементов на экран

cout << Arr[1] << '\n';

cout << Arr[2] << '\n';

Arr[0] = Arr[1] + Arr[2]; //Работа с элементами мало отличается от обычной работы с переменными, только нумерация в квадратных скобках

int x = Arr[0]; //Сохранение элемента массива в обычную переменную

}

Пример создания и обработки динамического массива:

#include <iostream>

using namespace std;

int main()

{

setlocale(LC_ALL, "Russian");

int n;

cout << "Введите количество элементов: ";

cin >> n;

int *arr = new int [n];

for (int i = 0; i <n; i++)

{

arr[i] = rand();

cout << arr[i]<<endl;

}

delete [] arr;

system ("pause");

return 0;

}

  1. Способы создания динамических массивов. Освобождение памяти, зарезервированной под динамический массив. Привести пример создания, инициализации и обработки динамического массива на языке С/C++.

Динамический массив— массив переменной длины, память под который выделяется в процессе выполнения программы.Функции динамического выделения памяти находят в оперативной памяти непрерывный участок требуемой длины и возвращают начальный адрес этого участка. Функции динамического распределения памяти: 

void* malloc(РазмерМассиваВБайтах); void* calloc(ЧислоЭлементов, РазмерЭлементаВБайтах); Для использования функций динамического распределения памяти необходимо подключение библиотеки 

#include <malloc.h> Поскольку обе представленные функции в качестве возвращаемого значения имеют указатель на пустой тип void, требуется явное приведение типа возвращаемого значения. Для определения размера массива в байтах, используемого в качестве аргумента функции malloc()требуется количество элементов умножить на размер одного элемента. Поскольку элементами массива могут быть как данные простых типов, так и составных типов (например, структуры), для точного определения размера элемента в общем случае рекомендуется использование функции  int sizeof(тип);

Пример malloc

// Выделение памяти int * arrayPtr = (int*)malloc(n*m * sizeof(int));

Пример с calloc

int * arrayPtr = (int*) calloc(size,sizeof(int)); // выделяем память под динамический массив целых чисел

Когда динамический массив (в любой момент работы программы) перестает быть нужным, то память можно освободить с помощью оператора delete.

Пример создания, инициализации и обработки динамического массива: см. вопрос 38.

  1. Динамические матрицы. Ввести размеры матрицы и выделить для нее место в памяти во время работы программы. Решить задачу 2 способами: выделять отдельный блок памяти для каждой строки; выделить память сразу на всю матрицу.

1 способ.

int size1=8,size2=8;

int **ptrarray = new int* [size1];//динамическое создание двуменого массива

for (int count=0;count<size1;count++)

{

ptrarray[count]=new int [size2];

}

for(int count=0;count<size1;count++) //освобождение памяти

{//удаление динамического массива

delete []ptrarray[count];

}

2 способ.

A = new pInt[M];

A[0] = new int [M*N]; //выделение памяти

for ( i = 1; i < N; i ++ ) A[i] = A[i-1]+ N; //расстановка указателей

delete A[0];

delete A; //освобождение памяти

  1. Привести пример реализации алгоритма обработки и преобразования матриц, используя динамическое выделение памяти и технику работы с указателями.

#include <iostream>

using namespace std;

int main()

{

int M, N;

cout <<"Razmer matrics: "; //для того, чтобы в матрице содержались элементы, лежащие ниже побочной диагонали, нужно, чтобы M > 1.

cin >>M >>N;

//динамически выделяем память под матрицу:

int **matrix = new int*[M];

int i, j, s;

for (i = 0; i < M; i++) {

matrix[i] = new int[N];

}

//вводим матрицу размера MxN.

for (i = 0; i < M; i++) {

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

matrix[i][j]=rand()%10;

}

}

cout <<"Matrics: \n";

for (i = 0; i < M; i++) {

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

cout<<matrix[i][j];

}

cout<<"\n";

}

for (s=0,i=0;i<M;i++)//нажождение суммы элементов выше главной диагонали

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

if(i<j)

{s+=matrix[i][j];}

cout<<"\n S="<<s;

//освобождаем память:

for (i = 0; i < M; i++) {

delete [] matrix[i];

}

delete [] matrix;

system("pause");

return 0;

}