Среда, 15.08.2018, 06:36
Discovery
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Форма входа
Категории раздела
PHP [1]
Уроки по PHP для начинающих
C++ [18]
Статьи посвященные С++
XML [2]
Статьи по XML
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
     Каталог статей
    -->
    Главная » Статьи » Программирование » C++

    Массивы в С++. Объявление, инициализация, использование.

    Массивы в С++. Объявление, инициализация, использование.

    Массив – коллекция переменных одного типа, обращение к которым происходит с применение общего для всех имен. Чтобы произвести какое-нибудь действие с такой переменной, нужно написать ее имя, указав в скобках ее числовой индекс. Например, так: array[10]. Встретить аналоги массива в реальной жизни очень трудно. Мы все уникальны. У каждого свое имя. Если имена совпадают, то в дополнение к ним люди придумали фамилию. А так как нас много и возможно, что наше имя и фамилия могут совпадать с именем и фамилией другого человека, нам от нашего отца достается отчество, которое нас делает еще уникальней. Вероятность встретить в одном месте двух человек, у которых совпадали бы имя, фамилия и отчество очень мала. Однако такое возможно. Вот пример из реальной жизни. В одной из средних школ учились в одном классе два ученика. Обоих звали Александрами. Оба были Морозовы. Вдобавок ко всему обоим от отца досталось одно и то же отчество: Георгиевич. Естественно встал вопрос, как их различать. Ведь не будешь же называть одного Морозов младший, а другого Морозов старший лишь на том основании, что один родился на несколько дней раньше другого. Выход нашелся сам собой. Им присвоили уникальные индексы. Один из них стал Морозов первый, а другой стал Морозов второй. Когда надо было вызвать одного, отвечать к доске, учительница произносила: «Морозов» - оба Морозовых напрягались. Потом она добавляла либо первый, либо второй. Один из них облегченно вздыхал, а другой шел отвечать к доске. В отличии от этого класса, в С++ индексация массива начинается с нуля. Чтобы обратиться к члену массива, нужно написать имя и индекс в квадратных скобках. Вот как будет выглядеть первый член массива array: array[0].

    Так же как и любую другую переменную в С++ массив нужно объявить, до того как он будет использован. Вот как выглядит объявление массива array, который содержит  10 переменных типа int:

    int array[10];

    Массивы удобны тем, что данные, находящиеся в массиве очень легко обрабатывать с помощью цикла. Внизу пример программы в которой с помощью цикла for( ) заполняется массив из десяти целых чисел начиная с единицы, а затем выводиться на экран.

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        int num[10];

        for(int i=0; i<10; i++)
        {
            num[i] = i+1;
            cout << num[i] << '\n';
        }

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

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

     #include <iostream>
    #include <cstdlib>
    #include <windows.h>
    using namespace std;

    int main()
    {
        int num[10];
        int i, j, k;
        int size = 10;

        cout << "Введите десять целых чисел.\n"
               << "После каждого введенного числа нажмите клавишу Enter: \n\n";

            for(i=0; i<size; i++)
            {
                cin >> num[i];
            }

        cout << "\n";

        // пузырьковая сортировка
        for(j=1; j<size; j++)
        {
            for(k=size-1; k>=j; k--)
            {
                if(num[k-1] > num[k])
                {

                    // Меняем элементы местами.
                    i = num[k-1];
                    num[k-1] = num[k];
                    num[k] =  i;
                }
            }
        }
        // Конец сортировки.

            // Отображаем отсортированный массив.
        cout << "Отсортированный массив: \n\n";

        for(i=0; i<size; i++)
            cout << num[i] << "\n";

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

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

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        int num[10] = {12, 56, 67, 45, 104, 98, 83, 125, 678, 900};
        int size = 10;

        cout << "Наш массив:\n";
        for(int i=0; i<size; i++)
        {
            cout << num[i] << "\n";
        }

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    Теперь несколько правил употребления массивов. Первый элемент массива всегда будет иметь индекс 0. Вот как будет выглядеть обращение к первому элементу массива array[] – array[0]. Второе правило: один массив нельзя присвоить другому массиву напрямую. Эта инструкция не скомпилируется: array1=array2, если array1 и array2 будут массивами. Только один элемент массива другому элементу другого массива. Вот пример программы, которая иллюстрирует это правило:

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        int num1[10] = {12, 56, 67, 45, 104, 98, 83, 125, 678, 900};

           int num2[10] = {35, 63, 125, 74, 112, 58, 83, 165, 578, 700};

        int i;
        int size = 10;

        cout << "Выводим массив num1:\n\n";
        for(i=0; i<size; i++)
        {
            cout << num1[i] << ", ";
        }
        cout << "\n\n";

        cout << "Выводим массив num2:\n\n";
        for(i=0; i<size; i++)
        {
            cout << num2[i] << ", ";
        }
        cout << "\n\n";

        cout << "Теперь присваиваем массив num1 массиву num2\n"
               << "и выводим их на экран.\n\n";

        for(i=0; i<size; i++)
        {
            num2[i]=num1[i];
        }

        cout << "Выводим массив num1:\n\n";
        for(i=0; i<size; i++)
        {
            cout << num1[i] << ", ";
        }
        cout << "\n\n";

        cout << "Выводим массив num2:\n\n";
        for(i=0; i<size; i++)
        {
            cout << num2[i] << ", ";
        }

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    В качестве индекса в С++ можно использовать только целые числа (в отличии от таких языков как PHP). Дробные числа, строки, отрицательные числа использовать нельзя.

    Ну и последнее, самое важное правило использование массивов в С++. В С++ не производиться проверка выхода за границы массива, т. к. создатели языка посчитали, что любая попытка такой проверки сделает язык более медленным. Язык С++ считается языком профессиональных программистов. Если вы объявите массив num[10], а затем попытаетесь обратиться к его тысячному элементу, то компилятор скомпилирует  вашу программу, и даже создаст исполняемый файл. При попытке записать какое-либо значение, вы всего вероятней запишете его поверх других данных, тем самым, повредив другие данные или даже операционную систему. Поэтому будьте осторожны, когда будете работать с массивами. Всегда смотрите, чтоб индексы элементов не выходили за границы массивов.

    Иногда бывает неудобно вручную подсчитывать количество элементов, когда мы инициализируем массив, во время объявления. Можно просто оставить квадратные скобки пустыми. Например, так: int num1[] = {12, 56, 67, 45, 104, 98, 83, 125, 678, 900}; . Компилятор сам подсчитает количество элементов. Вот еще один вариант программы, которая выводит массив на экран:

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        int num[ ] = {12, 56, 67, 45, 104, 98, 83, 125, 678, 900};
        int size = 10;

        cout << "Наш массив:\n\n";
        for(int i=0; i<size; i++)
        {
            cout << num[i] << ", ";
        }
        cout << "\n";

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    И так мы немного разобрались с массивами. Теперь давайте перейдем к более интересным вещам, а именно к строкам. Дело в том, что в С++ нет специального строкового типа. Для этого используется массив типа char. Каждый элемент такого массива содержит один символ, что дает потрясающие возможности для работы со строками в С++. Итак чтоб было понятно, что я имею ввиду я написал внизу программу, которая иллюстрирует это утверждение:

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        char string1[] = "Символ";
        char string2[] = {'С', 'и', 'м', 'в', 'о', 'л', '\0'};
        int i;

        cout << "Выводим string1: \n\n";

        i = 0;

        while(string1[i])
        {
            cout << string1[i];
            i++;
        }
        cout << "\n\n";

        cout << "Выводим string2: \n\n";

        i = 0;

        while(string2[i])
        {
            cout << string2[i];
            i++;
        }

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    Я специально использовал цикл while, чтобы выводить с помощью его каждый символ строк string1, и string2 на экран, хотя гораздо легче использовать инструкцию cout, чтобы продемонстрировать возможность доступа к любому символу наших строк.

    Перед тем, как двигаться дальше, давайте разберемся, что такое символьные литералы. Символьные литералы, это любой набор символов заключенный в двойные кавычки. Например: "Hello, World!"; "1234567", "!@#$%&" и так далее. Каждая такая строка заканчивается нулевым символом, который является признаком завершения строки. При инициализации массива типа char символьным литералом он добавляется автоматически. Поэтому если б мы, при объявлении массива, указывали бы размер нашего массива, то мы должны были бы указать, что в нашем массиве содержится семь элементов, а не шесть. Одни дополнительный элемент для признака завершения строки.

    Строку string2 мы инициализировали в ручную, заключив каждый символ в одинарные кавычки. В конце стоит символ '\0', это и есть символ завершения строки.

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

    Прежде чем я покажу все преимущества символьных массивов, я хотел бы поговорить о недостатках инструкции cin. Некоторым уже встречались с некоторыми странностями этой инструкции, когда с помощью нее пытаешься ввести несколько слов. Чтоб понять, о чем я говорю, скомпилируйте следующую программу и введите: «Hello, World!».

    #include <iostream>
    #include <windows.h>
    using namespace std;

    int main()
    {
        char string[80];

        cout << "Введите несколько слов: \n\n";
        cin >> string;
        cout << "\n\n" << string;

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    Как видим вместо «Hello, World!» наша программа вывела «Hello,». Дело в том, что оператор >> прекращает считывать строку, как только в ней встречается символ новой строки, пробел или знак табуляции. Для того, чтобы программа правильно считывала строку, лучше использовать функцию gets( ), указав в скобках имя символьного массива, в который вы хотите поместить вашу строку. Для того, чтобы можно было использовать эту функцию нужно поместить заголовок <cstdio>. Вот исправленный вариант предыдущей программы:

    #include <iostream>
    #include <cstdio>
    #include <windows.h>
    using namespace std;

    int main()
    {
        char string[80];

        cout << "Введите несколько слов: \n\n";
        gets(string);
        cout << "\n\n" << string;

        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    Ну а теперь немного практики... Как известно, нас часто просят ввести какие-то данные. Наш e-mail, телефон, имя, фамилию и так далее. Теперь представим, что мы попросили пользователя ввести номер телефона, чтоб потом его записать в свою базу данных. Но в любом случае, прежде чем сделать это, мы должны убедиться, что введенные данные корректны. В С++ много специальных функций для работы со строками (их мы подробнее будем изучать на следующем уроке), а сейчас воспользуемся лишь некоторыми из них. Во-первых, нам нужно определить, сколько символов содержится в веденном номере мобильного телефона. Во-вторых, нам нужно проверить, чтоб каждый символ был цифрой. И так вот что у меня получилось.

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <windows.h>
    using namespace std;

    int main()
    {
        char number[80];
        int length, digit;

        cout << "Введите номер вашего мобильного телефона\n"
               << "в формате 89990000000: \n\n";

        gets(number);

        length = strlen(number);

        if(length==11)
        {
            int i = 0;

            while(number[i])
            {
                digit = isdigit(number[i]);

                if(!digit)
                {
                    cout << "\nВы ввели не корректный номер вашего\n"
                           << "мобильного телефона.\n\n";
                    break;
                }
                  i++;
            }

            if(i==11)
            {
                cout << "\nВы ввели корректный номер телефона. Ваши данные \n"
                       << "обрабатываются. Подождите, это может занять \n"
                       << "несколько минут.\n\n";
            }
                  }
        else
        {
            cout << "\nВы ввели не корректный номер вашего\n"
                   << "мобильного телефона.\n\n";
        }
        cout << "\n\n";
        system("PAUSE");
        return 0;
    }

    Теперь давайте разбираться, как работает наша программа. Сначала мы с помощью функции gets( ) записываем значение введенное пользователем в символьный массив number. Для этого надо поместить имя массива в круглые скобки (для того, чтобы работать с этой функцией, надо написать в начале программы: #include <cstdio>;) . Далее мы подсчитываем, сколько символов ввел пользователь. Их должно быть ровно одиннадцать. Для этого мы используем функцию strlen( ). Для  работы с этой функцией мы должны записать в начале программы: #include <cstring>; . Количество символов в значении, введенном пользователем мы записываем в переменную length.

    Затем с помощью инструкции  if else проверяем, сколько символов ввел пользователь. Если количество символов равно 11, то проверяем, чтобы все они являются цифрами с помощью функции  isdigit( ), если их больше или меньше выводим с помощью else сообщение пользователю, что он ввел некорректный номер.

    Теперь посмотрим, как с помощью цикла while и функции isdigit( ) проверить, что все символы введенные пользователем являются цифрами. Для начала объявим переменную i, которую будем использовать в качестве счетчика, и инициализируем ее значением 0. В качестве условия цикла while поместим в его условие массив number и поместим вместо индекса переменную i. Так как первый элемент массива имеет индекс 0, и переменная i инициализирована нулем, то с первой же итерации массив while начнет проходить по массиву number. Так как любое ненулевое значение, помещенное в условие, преобразуется в истинное, то цикл while будет обрабатывать символ за символом, пока не будет достигнут признак завершения строки, который автоматически преобразуется в ложь, и работа цикла while прекращается.

    Затем с помощью функции isdigit( ) проверяем, является ли символ цифрой. Для того чтобы можно было работать с этой функцией в начале программы мы должны написать #include <cctype>. Если символ является цифрой, то результат работы функции будет не нулевое значение. Если символ не является цифрой, то результатом работы функции будет ноль. Результат помещаем в переменную digit. Затем с помощью инструкции if проверяем, какое значение содержит переменная digit. Здесь я хочу обратить ваше внимание на восклицательный знак перед переменной digit. Дело в том, что инструкция if будет выполняться только в том случае, если выражение, помещенное в условие инструкции if истинно. В нашем случае должно происходить все наоборот. Для этого мы перед переменной digit поставили знак логической инверсии. Поэтому если символ не является цифрой, в переменной digit присваивается значение 0, который преобразуется в ложь. А так как перед переменной digit стоит знак логической инверсии, то ложное значение преобразуется в истинное, а истинное в ложное. В результате код, записанный в инструкции if, будет выполняться только в том случае, если символ не является цифрой. Выводим сообщение пользователю о том, что он некорректно ввел номер мобильного телефона и выходим из цикла с помощью инструкции break так, как дальше обрабатывать данные нет смысла.

    Ну а дальше все просто. Когда цикл совершил одиннадцать витков, т. е. проверил все цифры, нужно вывести пользователю сообщение, что он ввел правильно номер телефона и введенные им данные обрабатываются. Для этого с помощью инструкции if проверяем, сколько итераций совершил цикл, и если переменная i равняется одиннадцати, выводим соответствующее сообщение. Единственным недостатком нашей программы, является то, что пользователь не может еще раз ввести номер своего телефона в случаи ошибки. В новом варианте нашей программы, эти недостатки исправлены. И так вот новый вариант нашей программы:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    using namespace std;

    int main()
    {
        char choice[80];
        int j = 0;

        for(;;)
        {

            j++;

            if(j>=2)
            {
                cout << "Вы хотите продолжить?(y/n)\n\n";

                gets(choice);

                if(!strcmp(choice, "n") || !strcmp(choice, "N"))
                {
                    exit(0);
                }
                cout << "\n";
            }

            for(;;)
            {
                char number[80];
                int length, digit;

                cout << "Ввидите номер вашего мобильного телефона\n"
                       << "в формате 89990000000: \n\n";

                gets(number);

                length = strlen(number);

                if(length==11)
                {
                    int i = 0;

                    while(number[i])
                    {
                        digit = isdigit(number[i]);

                        if(!digit)
                        {
                            cout << "\nВы ввели не корректный номер вашего\n"
                                   << "мобильного телефона. Попробуйте еще раз.\n\n";
                            break;
                        }
                          i++;
                    }

                    if(i==11)
                    {
                        cout << "\nВы ввели корректный номер телефона. Ваши данные \n"
                               << "обрабатываются. Подождите, это может занять \n"
                               << "несколько минут.\n\n";
                        break;
                    }
                }
                else
                {
                    cout << "\nВы ввели не корректный номер вашего\n"
                           << "мобильного телефона. Попробуйте еще раз.\n\n";
                }
                break;
            }
        }
        return 0;
    }

    Здесь мы неслучайно использовали два цикла for, у которых отсутствует инициализация, условие и инкремент. Так мы сделали цикл for бесконечным. Массив, содержащий данные пользователем и все переменные мы инициализировали внутри массива. Это не случайно. Дело в том, что переменные, инициализированные внутри цикла, создаются каждый раз, когда выполняется цикл, а после его завершения или выхода из него уничтожаются. Поэтому нам не надо обнулять их, если пользователь ввел неверные данные. С помощью инструкций break мы попадаем снова в первый цикл. Для того чтобы вопрос о том, хочет ли пользователь выйти из программы или хочет еще раз попробовать ввести номер телефона, не появился на экране при первой же попытки ввести номер телефона, с помощью переменной j мы узнаем, сколько раз пользователь вводит номер телефона. Если j будет равняться двум или более сообщение появиться на экране. Затем если будет нажата n или N, то программа завершит свою работу, выполнив функцию exit(0);. Если будет нажата другая буква, то пользователь может еще раз ввести номер своего мобильного телефона.

    Особенно я хотел бы обратить внимание на следующий код: if(!strcmp(choice, "n") || !strcmp(choice, "N")) . Дело в том, что результат работы функции в случае совпадения будет 0, который преобразуется в ложь. Восклицательный знак (логическое не) перед функцией strcmp преобразует ложное значение в истинное, а истинное в ложное.

    Ну, вот пока и все, что я хотел рассказать в этом уроке. В следующем уроке я расскажу про многомерные массивы, и покажу на примерах как их использовать в своих программах.

    Категория: C++ | Добавил: stranger140569 (07.02.2013)
    Просмотров: 15429 | Комментарии: 1 | Рейтинг: 5.0/1
    Всего комментариев: 0
    Имя *:
    Email *:
    Код *:
    Copyright MyCorp © 2018
    Конструктор сайтов - uCoz