
- •Int z[n]; //Неверно!
- •Урок 10. Рекурсивные функции
- •Int z[3]; //Массив
- •Урок 26. Конструкторы и деструкторы
- •Урок 27. Классы и указатели
- •Урок 28. Практика: список - добавление элементов
- •Урок 29. Показ элементов списка
- •Урок 30. Ищем элемент в списке
- •Урок 31. Пара вспомогательных методов для списка
- •Урок 32. Удаление элемента из списка
- •Урок 33. Функция с переменным числом параметров
- •Урок 34. Считаем элементы в списке
- •Урок 35. Обмен соседних элементов в списке
- •Урок 36. Получаем элемент списка по его номеру
- •Урок 36. Получаем элемент списка по его номеру
- •Урок 37. Сортируем элементы списка
- •Урок 38. Сортировка с перегрузкой оператора
Уроки по C/C++
Информационный
Канал Subscribe.Ru
C/C++. Урок 2. Массивы
Массив представляет из себя неколько переменных с одним именем и одного типа. К конкретному элементу массива можно обращаться по номеру. Вот пример:
//Объявление массива из 3 элементов.
int z[3];
//Инициализируем элементы массива.
z[0]=4;
z[1]=-4;
z[2]=13;
Обратите внимание, что при объвлении массива мы пишем в квадратных скобках именно столько элементов, сколько нам в надо. Если надо, чтобы в массиве было 10 элементов, значит пишем в квадратных скобках 10.
Нумерация элементов массива идет всегда с нуля. Другой возможности нет. Это в частности означает, что последний элемент массива будет иметь номер на 1 меньше, чем количество элементов массива. Т. е. если в массиве 10 элементов, то последний имеет номер 9.
Массивы могут быть многомерные. Вот пример:
//Объявление массива из 6 элементов.
int z[3][2];
//Заполняем элементы массива.
z[0][0]=4;
z[1][0]=-4;
Если внимательно посмотреть на объявление двумерного массива, то видно, что фактически он представляет из себя массив массивов.
Немного забегая вперед, скажем, что имя массива представляет из себя адрес начала массива (т. е. адрес начального элемента массива).
Элементы массива располагаются в адресном пространстве подряд. В частности для быстродействия это означает следующее - для доступа к любому элементу массива достаточно к адресу начала массива прибавить номер этого элемента, умноженный на размер, нужный для одного элемента. Т. е. для доступа к произвольному элементу массива не надо перебирать все предыдущие. В этом массивы отличаются от, например, списков - там для доступа к оперделенному элементу надо перебрать все предыдущие, что, разумеется, отражается на быстродействии.
При объявлении массива его размер должен быть известен заранее. Т. е. нельзя, например, сначала запросить у пользователя число n, а потом объявить массив:
Int z[n]; //Неверно!
Но если n объявлена перед этим как константа, то такое объявление массива вполне законно.
C/C++. Урок 3. Циклы for
В любом языке программирования есть, как правило, 2 типа циклов: те, про которые известно, сколько раз они должны выполнится и те, про которые заранее неизвестно, сколько раз они должны выполнится. Пример первого - это запрос у пользователя, например, 10 чисел (ясно, что мы должны повторить это действие 10 раз). Пример второго - запрос пароля у пользователя (неясно заранее, сколько попыток потребуется пользователю на ввод правильного пароля).
Циклы for относятся к первой категории. Они выполняются заранее известное число раз. Вот пример:
...
int z[3];
//Заполняем элементы массива.
for(int i=0; i<3; i++){
z[i]=i;
}
В этом примере мы заполняем элементы массива соответствующими числами.
После ключевого слова for мы пишем в круглых скобках параметры для цикла (обратите внимание, что после for обязательно должны идти общие круглые скобки). Параметры для цикла делятся на три части, которые мы разделяем точкой с зяпятой. Первая часть - это задание начального значения для переменой цикла. В нашем примере мы переменной i присваиваем значение 0 (но можно и любое другое). Вторая часть - это условие продолжения цикла. Если оно истинно, то цикл продолжает выполнение. Как только оно станет ложным, цикл прекратится. Третья часть - это изменение переменной цикла. Чаще всего переменная цикла изменяется на 1. i++ как раз и увеличивает i на 1 (можно было записать и так: i=i+1 - только так писать дольше).
Обратите внимание, что переменную i для цикла мы объявили прямо внутри цикла:
...
for(int i=0; ...){
...
Так часто и делают. Но, разумеется, i можно объявить и заранее:
int i;
...
for(i=0; ...){
...
Циклы for часто используются для перебора всех элементов массива. Вот так можно перебрать элементы двумерного массива:
int z[3][2];
//Заполняем элементы массива.
for(int i=0; i<3; i++){
for(int j=0; j<2; j++){
z[i][j]=0;
}
}
В цикле может быть и несколько переменных цикла. Вот пример:
int n=0;
for(int i=0, int j=0; i<3, j<2; i++, j++){
n++;
}
Этот цикл выполнится 2 раза и n по выходе из цикла будет равно 2. Синтаксис у такого цикла такой - имеются те же три части, между которыми пишем точку с запятой. Внутри каждой части в качестве разделителя пишем запятую. Цикл прекращается, если хотя бы одно из условий второй части (у нас это i<3, j<2;) окажется ложным.
Наверх
C/C++. Урок 4. Первая программа
Вот, наконец-то напишем первую программу. Вот ее текст:
#include <iostream.h>
void main(){
cout<<"Hello World!\n";
}
Эта программа после компиляции и запуска выведет на экран надпись "Hello World!".
Разберем текст программы. Начинаем ее со строчки
#include <iostream.h>
Это так называемая директива препроцессора. Все директивы препроцессора начинаются с символа #. Конкретно директива include нужна для включения некоторого файла в вашу программу. Тут мы включаем файл iostream.h. Он нужен для того, чтобы мы в нашей программе могли что-ниюудь вводить с клавиатуры или выводить на экран. Этот include пишется почти всегда. После директив препроцессора точка с запятой не ставится.
Далее в программе идет функция main. Функция с таким именем всегда должна присутствовать в любой консольной программе на C/C++ (причем только одна). Именно с нее (а не с первой строчки) начинается выполнение программы. Перед именем функции мы пишем тип возвращаемого значения (void означает, что функция ничего не возвращает - это аналог процедур в других языках программирования). После имени функции обязательно пишем круглые скобки. В них мы пишем парметры (если они есть). В нашем случае параметров нет.
Тело функции пишем в фигурных скобках. В нашем примере мы в теле пишем
...
cout<<"Hello World!\n";
...
cout - это экран монитора (точнее, стандартное устройство для консольного вывода (парвая буква c - от слова console, out - вывод)). На консоль (экран) мы отправляем строку "Hello World!". Обратите внимание, куда передается наше строка (<< - так как она передается влево, на консоль). Не путайте - так как символ >> тоже существует и используется для консольного ввода. В строке внутри кавычек мы видим символы \n. Это переход на новую строку. Сами символы \n печататься не будут.
Строки в C/C++ заключаются в двойные кавычки (в отличие от переменных типа char, значения для которых заключаем в одинарные кавычки).
В C/C++ любой оператор заканчивается на точку с запятой. Точка с запятой - это часть оператора, а не разделитель между операторами, как, например, в Delphi.
C/C++. Урок 5. Циклы while
Циклы while, в отличие от циклов for, предназначены для ситуаций, когда заранее неизвестно, сколько раз цикл должен выполнится.
Циклы while делятся на 2 типа: while и do-while. Принципиальная разница между ними такая - while может не выполнится ни одного раза, do-while выполняется по крайней мере 1 раз. Так что надо смотреть по задаче - если наше действие точно должно один раз выполнится (например при запросе у пользователя пароля), то выбираем do-while.
А вот и конкретный синтаксис:
while(a>0){
...//что-то делаем
};
Этот цикл будет выполятся до тех пор, пока a>0. Как только условие в крулых скобках станет ложным, цикл прекратит свою работу. Если же a будет сразу меньше или равно нулю, то цикл вообще ни разу не выполнится.
Пример цикла do-while:
int password;
do{
cout<<"\nEnter password";
cin>>password; //Ввод пользователем пароля.
}while(password!=123);
Этот цикл будет выполнятся до тех пор, пока пользователь не введет 123 в качестве пароля. Т. е. его условие продолжения такое же, как у while - пока условие в скобках истинно, цикл продолжает работу.
Обратите внимание, что после слова while условие продолжения цикла мы пишем в общих круглых скобках.
Также обратите внимание, что переменные, влияющие на истинность условия, как-то внутри цикла должны меняться - иначе мы можем оказаться в бесконечном цикле:
int a = 5;
while(a>0)
{
cout<<"*";//Бесконечный цикл.
}
Здесь всегда a больше 0 и из цикла мы никогда не выйдем.
C/C++. Урок 6. Директивы препроцессора
Мы уже сталкивались с одной директивой препроцессора в уроке 4. Сейчас мы обсудим, что такое.
До компиляция (т. е. превращение в машинные коды) вашей программы происходят некоторые действия - а именно сначала выполняются так называемые директивы препроцессора, а уже потом - непосредственно компиляция. Директивы препроцессора могут, например, включать в файл вашей программы другие файлы (это мы делаем с помощью директивы #include), определять некоторые константы (директива #define) и многое другое.
Важно понимать, что все директивы препроцессора выполняются до этапа компиляции. После выполнения директив препроцессора текст вашей программы будет изменен (не в исходном файле, конечно - там все как было, так и останется).
Перед любой директивой препрцессора пишется знак #.
Давайте немного приоткроем покров над тайной директив препроцессора на маленьком примере. Этот пример будет специфичен для Visual C++, но это не должно нас особенно тревожить - сейчас нам важно просто понять, как это все работает. Итак, создайте на Visual C++ новый проект для консольного приложения (для сего смотрите урок 1 в разделе по Visual C++ 6). Для файла *.cpp задайте имя test.cpp. В качестве текста программы введите
#include "test2.h"
#define pi 3.14
void main()
{
float z=2*pi;
}
Пока текст нас не слишком должен волновать. Если не все понимаете в тексте - не беда. Принцип здесь такой - #include влючает указанный файл в наш файл. У нас это файл test2.h. Создайте его (например в Блокноте) в той же папке, где находятся все остальные файлы вашего проекта. В нем напечатайте следующий текст (на самом деле можно напечатать все что угодно - это не принципиально):
struct v{
int x, y;
};
Еще одна директива препроцессора в нашей программе - это #define. Она просто пределяет константу pi, которую мы парой строчек ниже используем.
Теперь для просмотра того, что получается после выполнения директив препроцессора, измените настройки нашего проекта. Нажимайте Alt+F7 (или меню Project и далее Settings) и переходим на вкладку C/C++. В ней меняем содержимое окошка Project Options:
Из этого окошка все удалите, и напечатайте там
/MLd /Fo"Debug/" /P
Пока мы это обсуждать не будем, отметим только, что с такими параметрами вы получите в папке проекта файл с результатом работы препроцессора. Закройте окно настроек нажав на OK.
Компилируем программу (клавиша F7). В папке с файлами проекта появится файл test.i со следующим текстом:
#line 1 "D:\\_programming\\cpp\\test\\test.cpp"
#line 1 "D:\\_programming\\cpp\\test\\test2.h"
struct v{
int x, y;
};
#line 2 "D:\\_programming\\cpp\\test\\test.cpp"
void main()
{
float z=2*3.14;
}
Как вы видите, препроцессор поработал - вставил файл test2.h в наш файл и заменил pi на значение константы:
...
float z=2*3.14;
Так что работу препроцессера мы немного посмотрели.
C/C++. Урок 7. Константы
Константа - это понятное обзначения для некоторой величины, которая не должна менятся в программе. Например, вместо 3.1415926 в программе удобнее писать что-то типа pi.
Есть 2 способа объявления констант - через директиву препроцессора #define и через ключевое слово const.
Вот пример использования в программе констаны, объявленной через директиву #define:
#include <iostream.h>
#define SIZE 10
void main()
{
int z[SIZE];
for(int i=0; i<SIZE; i++)
{
z[i]=i;
}
int sum=0;
for(i=0; i<SIZE; i++)
{
sum+=z[i];
}
cout<<sum<<"\n";
}
А вот пример использования в программе константы, объявленной с помощью ключевого слова const:
#include <iostream.h>
const int size = 10;
void main()
{
int z[size];
for(int i=0; i<size; i++)
{
z[i]=i;
}
int sum=0;
for(i=0; i<size; i++)
{
sum+=z[i];
}
cout<<sum<<"\n";
}
Использование констант сильно упрощает процесс изменения в программе. Если вам надо увеличить размер массива в приведенных примерах, то вы просто изменяете константу.
Обратите внимание, что при объявлении массива таким способом:
...
int z[size];
...
size должна быть объявлена именно как константа. Если вы просто объявите size как целое, то компилятор выдаст ошибку.
Наверх
C/C++. Урок 8. Структуры
Структуры предназначены для хранения в одном месте различных данных, которые относятся к одному понятию. Скажем, данные для книги могут быть следующие: автор, название, количество страниц и т. п. И эти данные удобнее хранить не отдельно, а в одном месте.
Вот пример объвления и использования структур:
#include <iostream.h>
struct vector
{
//Координаты x и y вектора.
float x;
float y;
};
void main()
{
//Использование структуры vector.
vector d;
d.x=2;
d.y=-2.5;
}
Как вы видите, для объявления структуры используется ключевое слово struct.
Для доступа к полям внутри структуры используется оператор точка (.):
...
d.x=2;
Обратите внимание, что после закрывающей фигурной скобки при объявлении структуры надо обязательно ставить точку с запятой:
struct vector
{
...
};
Без нее компилятор выдаст сообщение об ошибке.
Внутри структур могут быть функции. Вот так может выглядеть наша структура с функциями:
struct vector
{
float x;
float y;
//Функция для записи x и y в вектор.
void SetVector(float x1, float y1){
x=x1;
y=y1;
}
//Функция для вывода вектора на консоль.
void ShowVector(){
cout<<"x="<<x<<", y="<<y<<"\n";
}
};
А вот так функции можно использовать:
vector d;
...
d.SetVector(5, 3);
d.ShowVector(); //Выведется "x=5, y=3".
Напоследок отметим, что развитием структур являются классы. Их мы рассмотрим на последующих занятих.
Урок 9. Функции
Функция представляет из себя отдельный кусок кода, который вы можете многократно использовать. Каждая функция имеет имя и может возвращать значение. Написав функцию один раз, вы можете использовать ее столько раз, сколько надо - для это мы вызываем ее по имени.
Вот пример:
//Объявление функции.
int sum(int a, int b)
{
return a+b;
}
void main()
{
//Вызов функции.
cout<<sum(3, 5);
}
Указанный фрагмент выведет, естественно, 8.
В нашем фрагменте мы объявили функцию sum, которая принимает два параметра целого типа - a и b. Обратите внимание, как мы пишем параметры. Во-первых, в круглых скобках и через запятую:
int sum(int a, int b)
...
Круглые скобки тут надо писать, даже если у функции нет вообще параметров:
int sum()
...
и во-вторых, тип мы пишем перед каждым параметром - скажем такое объявление функции будет неправильным:
int sum(int a, b)
...
Значение, которая функция возвращает, мы пишем после return:
int sum(int a, int b){
...
return a+b;
}
Тип возвращаемого значения должен совпадать с типом функции - раз перед именем функции мы написали int, то и после return надо написать нечто типа int.