Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ekzamennatsionnye_voprosy_2014-2015 (2).docx
Скачиваний:
14
Добавлен:
10.03.2016
Размер:
299.12 Кб
Скачать

2. Инициализация массивов

Как и простые переменные, массивы могут быть инициализированы при объявлении. Инициализатор для объектов составных типов (каким является массив) состоит из списка инициализаторов, разделенных запятыми и заключенных в фигурные скобки. Каждый инициализатор в списке представляет собой либо константу соответствующего типа, либо, в свою очередь, список инициализаторов. Эта конструкция используется для инициализации многомерных массивов.

Наличие списка инициализаторов в объявлении массива позволяет не указывать число элементов по его первой размерности. В этом случае количество элементов в списке инициализаторов и определяет число элементов по первой размерности массива. Тем самым определяется размер памяти, необходимой для хранения массива. Число элементов по остальным размерностям массива, кроме первой, указывать обязательно.

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

Примеры инициализации массивов:

nt a[3] = {0, 1, 2};

// Число инициализаторов равно числу элементов

double b[5] = {0.1, 0.2, 0.3};

// Число инициализаторов меньше числа элементов

int c[ ] = {1, 2, 4, 8, 16};

// Число элементов массива определяется по числу инициализаторов

int d[2][3] = {{0, 1, 2}, {3, 4, 5}};

// Инициализация двумерного массива. Массив состоит из двух строк, // в каждой из которых по 3 элемента. Элементы первой строки // получают значения 0, 1 и 2, а второй – значения 3, 4 и 5.

int e[3] = {0, 1, 2, 3};

// Ошибка – число инициализаторов больше числа элементов

Обратите внимание, что не существует присваивания массиву, соответствующего описанному выше способу инициализации.

int a[3] = {0, 1, 2};

// Объявление и инициализация

a = {0, 1, 2};

// Ошибка

  1. Си. Примеры работы с одномерными массивами: ввод/вывод

В языке C нет возможности вводить и выводить весь массив одним оператором ввода/вывода. Можно вводить и выводить только один элемент массива. Следовательно, для того чтобы ввести весь массив, надо использовать цикл.

int a[10], n;

printf("Введите количество элементов массива (от 0 до 9): ");

// Объявляем массив и переменную для количества элементов массива

scanf("%d", &n);

// Ввод количества элементов массива

if (n < 0 || n > 9)

{ printf("Количество элементов массива должно быть от 0 до 9!\n");

return;

}

// Если входные данные// то печатаем соответствующее сообщение и выходим из программы

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

// Ввод массива по одному элементу

scanf("%d", &a[i]);

// Можно использовать scanf("%d", a + i)

Вывод также осуществляется в цикле.

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

printf("a[%d] = %3d\n", i + 1, a[i]);

В результате на экране мы увидим примерно следующий текст: 

a[1] = 4

a[2] = 15

a[3] = -2

...

  1. Си. Примеры работы с одномерными массивами: суммирование значений

Даны три массива разной размерности. Определить в каком массиве больше сумма элементов.

#include <cstdio>

#include <locale.h>

const int nmax = 100;

 

int ArrayInput(int *n, double x[], char *fname);

// Функция ввода массива из файла

double Sum(double x[], int n);

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

{ double a[nmax], b[nmax], c[nmax];

double sa, sb, sc, max;

int na, nb, nc;

setlocale(LC_ALL, "rus");

// Функция поиска суммы элементов массива

// Меняем кодировку для консольного приложения

if (argc < 4)

{ printf("Недостаточно параметров!\n");

return;

}

if (!ArrayInput(&na, a, argv[1]))

return;

if (!ArrayInput(&nb, b, argv[2]))

return;

if (!ArrayInput(&nc, c, argv[3]))

return;

sa = Sum(a, na);

sb = Sum(b, nb);

sc = Sum(c, nc);

max = sa;

if (sb > max) max = sb;

if (sc > max) max = sc;

if (sa == max)

printf("Массив А имеет максимальную сумму элементов: %9.3lf\n", max);

if (sb == max)

printf("Массив B имеет максимальную сумму элементов: %9.3lf\n", max);

if (sc == max)

printf("Массив C имеет максимальную сумму элементов: %9.3lf\n", max);

}

double Sum(double x[], int n)

{ double s = 0;

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

s += x[i];

return s;

}

int ArrayInput(int *n, double x[], char *fname)

{ FILE *file;

if ((file = fopen(fname, "r")) == NULL)

{ printf("Невозможно открыть файл '%s'\n", fname);

return 0;

}

if (fscanf(file, "%d", n) < 1)

{ printf ("Ошибка чтения из файла '%s'\n", fname);

fclose(file);

return 0;

}

if (*n < 0 || *n > nmax)

{ printf("Кол-во эл-тов массива должно быть от 1 до %d! (файл '%s')\n", nmax, fname);

return 0;

}

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

if (fscanf(file, "%lf", &x[i]) < 1)

{ printf ("Ошибка чтения из файла '%s'\n", fname);

fclose(file);

return 0;

}

fclose(file);

return 1;

}

  1. Си. Примеры работы с одномерными массивами: нахождение максимального элемента

#include <iostream>

using namespace std;

int main()

{

int m[10],I , min ,max;

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

cin>>m[i];

}

max=m[0];

for(i=1;i<10;i++){

if(max<m[i])max=m[i];

}

min=m[0];

for(i=1;i<10;i++){

if(min>m[i]) min = m[i];

}

cout<<"min = "<<min<<endl;

cout<<"max = "<<max;

system("PAUSE");

return 0;

}

  1. Си. Примеры работы с одномерными массивами: циклический сдвиг

//Cдвигает элементы массива на 1 влево

#include <iostream>

#include <iterator>

#include <algorithm>

int main() {

std::size_t const arraySize = 10;

int array[arraySize] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

std::rotate(array, array + 1, array + arraySize);

std::copy(array, array + arraySize, std::ostream_iterator<int>(std::cout, " "));

std::cout << std::endl;

}

  1. Си. Примеры работы с одномерными массивами: поиск элемента

/* Бинарный поиск */

#include

main()

{

int k[100],v,i,j,m;

104

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

scanf("%d",&k[i]);

scanf("%d",&v);

i=0; j=100; m=50;

while (k[m]!=v)

{

if (k[m] < v) i+=m;

else j=m-i;

m=(i+j)/2;

}

printf("%d %d",v,m);

}

  1. Си. Примеры работы с одномерными массивами: алгоритмы сортировки массивов

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

template< class T >

void selectSort(T* arr, int size)

{

    T tmp;

    for(int i = 0; i < size; ++i) // i - номер текущего шага

    {

        int pos = i;

        tmp = arr[i];

        for(int j = i + 1; j < size; ++j) // цикл выбора наименьшегоэлемента

    {

           if (arr[j] < tmp)

         {

               pos = j;

               tmp = arr[j];

           }

        }

        arr[pos] = arr[i];

        arr[i] = tmp; // меняем местами наименьший с a[i]

    }

}

Сортировка пузырьком(обменом)

Идея метода: шаг сортировки состоит в проходе снизу вверх по массиву.По пути просматриваются пары соседних элементов. Если элементы некоторой пары находятся в неправильном порядке, то меняем их местами.

template< class T >

void bubbleSort(T* arr, int size)

{

    T tmp;

 

    for(int i = 0; i < size - 1; ++i) // i - номер прохода

    {            

        for(int j = 0; j < size - 1; ++j) // внутренний цикл прохода

        {    

            if (arr[j + 1] < arr[j])

            {

                tmp = arr[j + 1];

                arr[j + 1] = arr[j];

                arr[j] = tmp;

            }

      }

    }

}

Сортировка вставками

Сортировка простыми вставками в чем-то похожа на вышеизложенные методы.

template< class T >

void insertSort(T* a, int size)

{

    T tmp;

    for (int i = 1, j; i < size; ++i) // цикл проходов, i - номер прохода

    {

        tmp = a[i];

        for (j = i - 1; j >= 0 && a[j] > tmp; --j) // поиск места элемента в готовой последовательности

            a[j + 1] = a[j];    // сдвигаем элемент направо, пока не дошли

        a[j + 1] = tmp; // место найдено, вставить элемент    

    }

}

Сортировка Шелла Сортировка Шелла является довольно интересной модификацией алгоритма сортировки простыми вставками.

int increment(long inc[], long size)

{

    int p1, p2, p3, s;

    p1 = p2 = p3 = 1;

    s = -1;

    do

    {

   if (++s % 2)

        {

            inc[s] = 8*p1 - 6*p2 + 1;

        }

        else

        {

            inc[s] = 9*p1 - 9*p3 + 1;

            p2 *= 2;

            p3 *= 2;

        }

    p1 *= 2;

    }

    while(3*inc[s] < size);  

 

    return s > 0 ? --s : 0;

}

 

template< class T >

void shellSort(T a[], long size)

{

    long inc, i, j, seq[40];

    int s;

 

    s = increment(seq, size); // вычисление последовательности приращений

    while (s >= 0)  // сортировка вставками с инкрементами inc[]

    {

         inc = seq[s--];

         for (i = inc; i < size; ++i)

         {

             T temp = a[i];

             for (j = i-inc; (j >= 0) && (a[j] > temp); j -= inc)

                a[j + inc] = a[j];

             a[j] = temp;

         }

    }

}

Пирамидальная сортировка

Пирамидальная сортировка является первым из рассматриваемых методов, быстродействие которых оценивается как O(n log n)

template< class T >

void downHeap(T a[], long k, long n)

{

    //  процедура просеивания следующего элемента

    //  До процедуры: a[k+1]...a[n]  - пирамида

    //  После:  a[k]...a[n]  - пирамида

    T new_elem;

    long child;

    new_elem = a[k];

   

    while(k <= n/2) // пока у a[k] есть дети

    {      

        child = 2*k;

       

        if( child < n && a[child] < a[child+1] ) //  выбираем большего сына

            child++;

        if( new_elem >= a[child] )

            break;

        // иначе

        a[k] = a[child];    // переносим сына наверх

        k = child;

    }

    a[k] = new_elem;

}

 

template< class T >

void heapSort(T a[], long size)

{

    long i;

    T temp;

 

  // строим пирамиду

    for(i = size / 2 - 1; i >= 0; --i)

        downHeap(a, i, size-1);

 

  // теперь a[0]...a[size-1] пирамида

 

    for(i=size-1; i > 0; --i)

    {

        // меняем первый с последним

        temp = a[i];

        a[i] = a[0];

        a[0] = temp;

        // восстанавливаем пирамидальность a[0]...a[i-1]

        downHeap(a, 0, i-1);

    }

}

  1. Си. Символьные строки: объявление символьных строк

Объявить строку = выделить ей место в памяти и присвоить имя.

char s[80]; //выделяется 80 байт, в строке – «мусор» )

char s1[80] = "abc"; //выделяется 80 байт, занято 4 байта (с учетом '\0')

char qqq[] = «Руслан"; // выделяется 7 байт

(с учетом '\0')

Задача: ввести слово с клавиатуры и заменить все буквы «а» на буквы «б».

main()

{

char q[80];

int i;

printf("Введите строку\n");

scanf( "%s", q);

i = 0;

while ( q[i] != '\0' ) {

if ( q[i] == 'а' ) q[i] = 'б';

i ++;

}

printf ( "Результат: %s ", q );

}

  1. Си. Символьные строки: функции для работы со строками

Таблица 1 — Функции для работы со строками и символами

Функция

Пояснение

strlen(имя_строки)

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

Копирование строк

strcpy(s1,s2)

выполняет побайтное копирование символов из строки  s2 в строку s1

strncpy(s1,s2, n)

выполняет побайтное копирование n символов из строки  s2 в строку s1. возвращает значения s1

Конкатенация строк

strcat(s1,s2)

объединяет строку s2 со строкой s1. Результат сохраняется в s1

strncat(s1,s2,n)

объединяет n символов строки s2 со строкой s1. Результат сохраняется в s1

Сравнение строк

strcmp(s1,s2)

сравнивает строку s1 со строкой s2 и возвращает результат типа int: 0 –если строки эквивалентны, >0 – если s1<s2,  <0  — если s1>s2 С учётом регистра

strncmp(s1,s2)

сравнивает n символов строки s1 со строкой s2 и возвращает результат типа int: 0 –если строки эквивалентны, >0 – если s1<s2,  <0  — если s1>s2 С учётом регистра

stricmp(s1,s2)

сравнивает строку s1 со строкой s2 и возвращает результат типа int: 0 –если строки эквивалентны, >0 – если s1<s2,  <0  — если s1>s2 Без учёта регистра

strnicmp(s1,s2)

сравнивает n символов строки s1 со строкой s2 и возвращает результат типа int: 0 –если строки эквивалентны, >0 – если s1<s2,  <0 — если s1>s2 Без учёта регистра

Обработка символов

isalnum(c)

возвращает значение true, если с является буквой или цифрой, и false в других случаях

isalpha(c)

возвращает значение true, если с является буквой,  и false в других случаях

isdigit(c)

возвращает значение true, если с является цифрой, и false в других случаях

islower(c)

возвращает значение true, если с является буквой нижнего регистра, и false в других случаях

isupper(c)

возвращает значение true, если с является буквой верхнего регистра, и false в других случаях

isspace(c)

возвращает значение true, если с является пробелом, и false в других случаях

toupper(c)

если символ с, является символом нижнего регистра, то функция возвращает преобразованный символ с в верхнем регистре, иначе символ возвращается без изменений.

Функции поиска

strchr(s,c)

поиск первого вхождения символа с в строке sВ случае удачного поиска возвращает указатель на место первого вхождения символа сЕсли символ не найден, то возвращается ноль.

strcspn(s1,s2)

определяет длину начального сегмента строки s1, содержащего те символы, которые не входят в строку s2

strspn(s1,s2)

возвращает длину начального сегмента строки s1, содержащего только те символы, которые входят в строку s2

strprbk(s1,s2)

Возвращает указатель  первого вхождения любого символа строки s2 в строке s1

Функции преобразования

atof(s1)

преобразует строку s1 в тип double

atoi(s1)

преобразует строку s1 в тип int

atol(s1)

преобразует строку s1 в тип long int

Функции стандартной библиотеки ввода/вывода <stdio>

getchar(с)

считывает символ с со стандартного потока ввода, возвращает символ в формате int

gets(s)

считывает поток символов со стандартного устройства ввода в строку s до тех пор, пока не будет нажата клавиша ENTER

  1. Си. Указатели: описание, инициализация, операции с указателями

  2. Си. Структуры. Массивы структур

Структура – это сложный тип данных представляющий собой упорядоченное в памяти множество элементов различного типа. Каждый элемент в структуре имеет свое имя и называется полем. В СИ элементы структуре располагаются последовательно, а размер структуры определяется суммой размеров всех элементов.   Объявление в СИ структуры имеет вид:    struct [имя типа]    {     поле_1;     поле_2;     ...     поле_N;    } [список переменных];  Объявление полей структуры возможно только без инициализации. Если несколько полей следующих друг за другом в описании структуры имеют один и тот же тип, то для их описания можно использовать синтаксис объявления нескольких переменных одного и того же типа. Типом поля может быть любой тип (как системный, так и пользовательский), описанный ранее.  Примеры структур:   Пример структуры в СИ, содержащая информацию о точке в двумерном пространстве (координаты):    struct Point    {     double x, y;    };  А вот структура в СИ, содержащая информацию об окружности:    struct Circle    {     double x, y, r;    };   Структура, содержащая информацию о студенте (фамилия, имя, отчество, номер зачетной книжки, средний балл):    struct Student    {     char sname[20], name[20], patronymic[20];     unsigned int num;     double mark;    };  Структура в СИ, содержащая информацию о группе студентов (название группы, количество студентов, список студентов (максимально 30)):    struct Group    {     char name[10];     unsigned number;     struct Student list[30];    }; 

  1. Си. Организация линейных списков

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]