Главная

Категории:

ДомЗдоровьеЗоологияИнформатикаИскусствоИскусствоКомпьютерыКулинарияМаркетингМатематикаМедицинаМенеджментОбразованиеПедагогикаПитомцыПрограммированиеПроизводствоПромышленностьПсихологияРазноеРелигияСоциологияСпортСтатистикаТранспортФизикаФилософияФинансыХимияХоббиЭкологияЭкономикаЭлектроника






Методика создания программ в Microsoft Visual Studio.


Введение

Изучить программирование непросто. Изучать программирование на языке С++ непросто вдвойне. Создатель языка С++ Бьёрн Страуструп задумывал его как язык для профессионалов ‑ краткий, хорошо подходящий как для системного программирования так и создания прикладных программ.

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

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

 

v Таким значком отмечены определения всех терминов.

& Так выделяются советы по наиболее эффективной работе.

þ Так – важные замечания.

А так – вопросы и упражнения. Упражнения повышенной сложности отмечены значком *.

 

Глава 1. Основы.

1.1. Структура программы на С++. Комментарии.

Изучение C++ начнем с рассмотрения простейшей программы[1], которая выводит на экран сообщение.

// программа first.cpp

#include <iostream.h>

Int main()

{

cout << "Hello!"; /* вывод текста

на экран */

return 0;

}

Для вывода символов используется конструкция cout. После двух символов // начинается пояснительный текст комментария, который игнорируется компилятором. Комментарий может начинаться с любой позиции и действует до конца строки. Наряду с новым типом комментариев действует и старый, применяемый в С. Текст комментария заключается между символами /* и */.

Программа С++ строится из отдельных блоков, называемых функциями. В нашем примере программа очень поста и состоит из одной функции с именем main(). Она содержит следующие элементы:

- директиву препроцессора #include

- заголовок функции int main()

- тело функции, ограниченное фигурными скобками { и }

- оператор return, завершающий выполнение функции.

Несколько пояснений. При создании исполняемого кода используется препроцессор - специальная программа, которая обрабатывает исходный файл перед компиляцией. Директива #include <iostream.h>приводит к тому, что в программу добавляется содержимое файла iosteram.h . Обновленный файл обрабатывается на следующем шаге компиляции.

þ Буквы io в слове iostream означают input/output (ввод/вывод). Помните, программы, которые для ввода и вывода используют конструкции cout и cin (см. раздел 1.3) должны включать файл iostream.h!

Программа на С++ обязательно должна содержать функцию с именем main(). (не MAIN(), Main() и т.д., так как С++ чувствителен к выбору регистра). Вместо int main() допустимо использовать void main(), тогда оператор return в конце главной функции не используется. Выражение void (пустой), так же как и return 0, означает, что функция main не возвращает никаких значений.

Для создания исполняемого файла достаточно набрать код программы в любом текстовом редакторе и обработать специальной программой - компилятором, который переводит конструкции языка в машинные коды. Однако гораздо удобнее использовать для этих целей так называемую визуальную среду разработки, например, Microsoft Visual Studio. Познакомимся с ней подробнее.

Ввод-вывод.

В нашей первой программе для вывода текста на экран мы использовали потоковый вывод cout <<”Hello” характерную для С++. Потоковый вывод cout и потоковый ввод cin заменяют привычные для C операторы printf и scanf. Впрочем, если вам нравится ими пользоваться, С++ позволяет это делать, только не забудьте добавить в программу заголовочный файл stdio.h.

þ Не допускайте в программе одновременного использования старого (как в С) и нового метода ввода-вывода. Это может привести к непредсказуемым для работоспособности программы последствиям!

Потоковый ввод-вывод работает более разумно, чем операторы ввода-вывода в стиле С. Так, cout «понимает» в каком случае следует вывести строку символов, а в каком значение переменной (о переменных см. ниже). Кроме того, объект cout может управлять выводом на экран также хорошо, как и оператор printf. Учитывая, что настоящие учебное пособие не претендует на объем справочного руководства, приемы работы с потоковыми объектами cout и cin вводятся постепенно, по мере необходимости. С некоторыми особенностями управления потоковым вводом-выводом можно ознакомится в Приложении.

Переменные и константы.

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

v Переменные - это именованные ячейки памяти, в которых хранятся данные и над которыми программы выполняют вычисления.

Для переменных рекомендуется выбирать имена, имеющие смысл. При этом следует руководствоваться правилами:

- в именах можно использовать буквы латинского алфавита, цифры и символ подчеркивания;

- первый символ не может быть цифрой;

- в качестве имен нельзя использовать ключевые слова языка с++[A1] ;

- символы верхнего и нижнего регистров рассматриваются как разные.

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

Как уже упоминалось, переменные ассоциируются с данными. В С++ используются две группы данных: основные и производные от них. Основные типы данных служат для представления целых и вещественных чисел:

int - хранит целое число от -2147483648 до +2147483647 (занимает 4 байта);

double - хранит число с плавающей точкой двойной точности (занимает 8 байт). Вещественное число может быть представлено десятичной дробью (например, 76.342) или в так называемом экспоненциальном виде: -18.32e13 (что означает -18.32∙1013 ). В приведенном примере -18.32 называется мантиссой, а 13 – показателем степени числа 10. Максимальный показатель степени для типа double составляет 308, а минимальный -307.

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

short - хранит целое число от -32768 до +32767 (занимает 2 байта);

float - хранит число с плавающей точкой одинарной точности (занимает 4 байта), максимальный и минимальный показатель степени 38 и -37 соответственно;

а также

char - в основном, используется для хранения символов, численных значений от ‑128 до +127 (занимает 1 байт).

Есть еще и другие типы, но эти – наиболее популярные.

В С++ работает строгое правило – все переменные, до того как будут использованы, должны быть определены. При этом не важно, в каком месте программыНапример, так:

Десятичная константа

Арифметические операции.

К любой комбинации основных типов переменных могут применяться арифметические операции: сложения, вычитания, умножения и деления, которые выполняются с помощью операторов: +, -, *, / (как и в других языках). Кроме того, над целыми числами и целочисленными переменными может выполняться операция % ‑ получения остатка:

k = 7%2 // результат равен 1

В языке С++ используется традиционные правила приоритета операций. Достойным отдельного упоминания являются инкремент и декремент ++ и --. Пример:

i++; //i увеличивается на 1. Равносильно i=i+1; j--; //j уменьшается на 1. Можно написать и --j;

Между вариантами d++ и ++d есть некоторая разница. Сравните:

int d=1, e; e=d++; //После этого оператора d=2, e=1

и

int d=1, e;e=++d; //После этого оператора d=2, e=2

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

sum += i; // Равносильно sum=sum+i;prod *= k; // Равносильно prod = prod*k; Разумеется, такая форма записи возможна для всех арифметических операторов.

þ На начальном этапе изучения С++ рекомендую не очень “зацикливаться” на этих операциях. Писать эффективные программы можно и без их использования, впрочем, более подробно их описание приводится в Приложении 1.

Как писал Бьёрн Страуструп, при присваивании и арифметических операциях C++ выполняет все осмысленные преобразования между основными типами, чтобы их можно было сочетать без ограничений:

double d = 1;

int i = 1;

d = d + i;

i = d + i;

þ Очевидно, что последнее преобразование чревато ошибкой, так как длина целочисленной переменной iменьше длинывещественной переменной d !

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

d = d + double(i);

Явное преобразование типов, выполненное к переменной типа char, позволяет получить ее номер в таблице символов ASCII. И наоборот, явно преобразуя целочисленную переменную к типу char, получаем соответствующий её номеру символ в ASCII – таблице:

#include <iostream.h>

Void main()

{

int i;

cout<<”input integer number < 128 ”; // приглашение ввести целое число,

// меньшее 128

cin>>i; // ввод числа с клавиатуры

cout<<char (i)<<endl; // явное преобразование, вывод символа

}

В приведенном примере используется потоковый ввод значения переменной со стандартного устройства ввода (клавиатуры) при помощи cin. Строка текста, которая предшествует объекту cin не обязательна, но очень полезна, т.к. поясняет пользователю программы, что от него требуется. Обратите внимание на специальное «слово» - endl. Оно предписывает после вывода символа char(i) перевести курсор на новую строку.

Контрольные вопросы. А

Void main()

{

double x, y=10.25;

x = sqrt(y); // x – переменная которой присваивают значение

// у – аргумент (информация, передаваемая функции)

cout<<” x= ”<<x;

}

Здесь: sqrt – имя функции, в скобках – аргумент функции. Важно, чтобы тип возвращаемого значения функции соответствовал типу переменной х, а тип ее аргумента – типу переменной y. Сведения об этом передаются компилятору посредством прототипа[2] функции. Прототип функции sqrt( ) – выражение вида

double sqrt(double);

Первое double означает, что функция sqrt( ) возвращает значение типа double, а второе double в круглых скобках означает, что функции требуется аргумент типа double.

Перед применением функции в программу следует включить ее прототип. Прототип функции sqrt, как и других встроенных математических функций, описаны в заголовочном файле math.h, поэтому для использования встроенных математических функций в программу следует включить заголовочный файл math.h.Все встроенные математические функции, за исключением abs( ), labs( ) могут принимать и возвращать значения типа float, long, double.

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

Гиперболические функции

double sinh(double arg);//гиперболический синус.

duble cosh(double arg);//гиперболический косинус.

double tanh(double arg);//гиперболический тангенс.

 

Другие элементарные функции

int abs(int num);//абсолютное значение целого числа. Тип аргумента – int.

long labs(long arg);// абсолютное значение целочисленной переменной

// типа long.

double fabs(double arg);//абсолютное значение вещественного числа double fmod(double x, double y);// остаток от деления х/у.

 

У студентов и преподавателей популярностью пользуется еще одна функция – rand(),которая возвращает случайные целые числа, равномерно распределенные от 0 до значения, задаваемого константой RAND_MAX. Прототип функции:

int rand(void); // функция используется без аргумента

Для использования этой функции необходимо подключить заголовочный файл stdlib.h.

Контрольные вопросы. А.

 

Оператор if else

Оператор if-else имеют следующий синтаксис:

If (условие)

оператор1;

Else

оператор2;

Еслиусловиеистинно, (т.е. отлично от 0), то выполняется оператор1; иначе выполняется оператор2.

// пример:

if(a != 0) // если a не равно нулю

c=b/a; // выполняем какие-то действия...

else // иначе:

cout<<”error!”;// выводим сообщение об ошибке

Возможна более простая конструкция оператора, без else:

If (условие)

оператор1;

оператор2;

В этом случае, если условиеложно, сразу выполняется следующий за if оператор2.

// пример

if(chSym != 'y') return; // если chSym не равно ‘y’, то выполняем

// оператор return

При помощи фигурных скобок можно объединить выполнение нескольких операторов:

// пример:

if(var1 == 0 && var2 > 0) // если var1 равно нулю И var2 больше нуля, то:

{

var1=10;

var2=var1/2;

cout<<var2; // выполняем какие-то действия...

}

Else

{

var1=1;

var2=1; // выполняем другие действия...

}

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

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

if( !var1 && var2>0) // если var1 равно нулю И var2 больше нуля, то:

{

… // выполняем какие-то действия...

}

else{ // иначе:

… // выполняем другие действия...

}

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

int i;

cin>>i; //ввод значения с клавиатуры

if (((i>= 10) && (i<= 100))&&(i%3==0))

cout<<i<<endl;

Else

cout<<”error”;

Так как приведенные условия должны выполняться одновременно, в листинге используется логический оператор И - &&. Обратите внимание на группирующие скобки, которые настоятельно рекомендую использовать для определения приоритета выполнения логических операций.

Конструкция if else if

Комбинируя вместе несколько операторов if else, можно смоделировать конструкцию выбора более чем из двух возможных вариантов:

if(ch==’A’)

up++; // альтернатива 1

Else

if(ch==’B’) // альтернатива 2

down++; // подальтернатива 2a

Else

Down--; // подальтернатива 2b

Если ch не равно ‘A’> программа переходит к else. Второй оператор if else разветвляет эту альтернативу еще на две возможности. Свободное форматирование позволяет расположить эти элементы другим способом, более удобным для чтения:

if(ch==’A’)

up++; // альтернатива 1

else if(ch==’B’)

down++; // альтернатива 2

Else

Down--; // альтернатива 3

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

Различные варианты вложения if elseможет вызвать затруднение в понимании, какому if соответствует else ? Рассмотрим пример:

int number;

cin>>number; // ввод значения number

if(number>=10)

if(number<21)

cout<<”1: number=”<<number;

Else

cout<<”2: number=”<<number;

cout<<”3: number=”<<number;

Чтобы понять, какую строку выведет программа, следует запомнить правило: else соответствует ближайшему if. Таким образом, несмотря на форматирующие отступы, else относится не к первому, а ко второму if.Следовательно, если введено любое значение number меньше 10 (например, 7), то управление будет передано на оператор, следующий за условными операторами. На экран будет выведено:

3 : number = 7

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

int number;

cin>>number;

if(number>=10)

{

if(number<21)

cout<<”1: number=”<<number; // будет выполняться при number >=10 и <21

}

Else

cout<<”2: number=”<<number; // будет выполняться при number < 10

cout<<”3: number=”<<number; // будет выполняться всегда

Условный оператор.

В языке С++ имеется оператор, который может использоваться вместо оператора if else. Это условный оператор и записывается как ?:. Общий формат оператора:

выражение1 ? выражение2 : выражение3;

Если выражение1 истинно, то значением всего условного оператора является выражение2, в противном случае - выражение3.

// пример

int c=a>b ? a : b; // если a>b, то с=a, иначе с=b

Как видим, условный оператор в данном примере приводит к тому же результату, что и выражение

int c;

if(a>b)

c=a;

Else

c=b;

По сравнению с последовательностью if else, условный оператор более лаконичен, но и менее нагляден. Злоупотребление условным оператором может послужить «эффективным» способом сокрытия смысла программного кода.

Оператор switch.

Выше мы уже приводили пример использования вложенной конструкции else if else для организации выбора между множественными альтернативами. В С++ имеется другая конструкция, которая служит этим же целям – оператор switch. Общая форма оператора:

Switch(dvalue)

{

Switch(choise)

{

case ’a’:

case ’A’: cout<< ” abort”;

break;

case ’r’:

case ’R’: cout<< ” report”;

break;

default: cout<< ” That’s not a choise”;

}

Поскольку за меткой case ’a’: отсутствует оператор break, выполнение программы продолжается со следующей строки, с оператора, который расположен сразу после case ‘A’:.

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

Как видим, и оператор switch, и оператор if else позволяют осуществить выбор из списка альтернативных вариантов. Оператор if else более гибок, в частности он позволяет обрабатывать диапазоны значений.

if (age>17 && age<20)

code=0;

else if (age>=20 && age<35)

code=1;

else if (age>=35)

code=2;

Else

code=3;

Оператор switch не предназначен для обработки диапазонов. Кроме того, значение метки должно быть константой, а вариант метки – целым (включая тип char), поэтому switch не будет обрабатывать вещественные числа. Однако, если возможно, используйте оператор switch, так как это более эффективно с точки зрения скорости выполнения и размера программы.

Операторы цикла.

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

Оператор for

Следующий листинг показывает, что можно делать с помощью оператора цикла for:

#include <iostream.h>

Void main()

{

Loops stop

Как видно, оператор for поэтапно выполняет следующие действия.

- Задает начальное значение переменной цикла ( i = 0).

- Проверяет условие выполнения цикла (i<5).

- Выполняет действия внутри тела цикла, если условие истинно. Как только условие становится ложным – цикл прекращается.

- Выполняет операцию над переменной цикла в каждой итерации, в данном случае – это операция инкремента, т.е. увеличения значения переменной на единицу.

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

 

#include <iostream.h>

Void main()

{

int aval, sum=0;

for(int i=0; i<5; i++) // можно определить переменную цикла здесь

{

cout << ” input number\n”;

cin<<aval;

sum = sum + aval;

}

cout << ” Sum equal ”<<sum;

}

 

Интересно, что условие выполнения цикла не обязательно должно принимать значение истина/ложь, так как в С целочисленное значение равное 0 эквивалентно логическому ложь, а не равное нулю - истина. Таким образом, если значение выражения станет равным нулю, то выполнение цикла прекратится.

int limit=4;

Изменение шага цикла

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

// пример: шаг цикла by вводится пользователем

#include <iostream.h>

Void main()

{

cout<<” Enter an integer\n ”

int by;

cin>>by;

cout<<” Step is: ”<<by<<”\n”;

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

cout << i<<”\n”;

}

Результат действия этой программы:

Enter an integer

Step is: 33

Когда значение iстановится равным 132, выполнение цикла прекращается.

В качестве обновления переменной можно использовать любое действительное (с синтаксической точки зрения) выражение:

i=2*i;

i=i*i+1;

и т.д.

Рассмотренный цикл for является циклом с предусловием, т.е. условие выполнения цикла проверяется перед циклом, и если условие с самого начала является ложным, то программа вообще не выполнит цикла. К такому же типу можно отнести и цикл while.

Цикл while.

Цикл whileнапоминает собой цикл for без частей инициализации и обновления цикла.

while( условие выполнения цикла)

Тело цикла;

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

// этот цикл будет выполняться бесконечно

// пока не будет прерван нажатием Ctrl+C

int i=10;

while(i>0)

{

cout << ” i= ”<<i<<”\n”;

}

// а этот цикл выведет на экран 10 значений переменной i

int i=10;

while(i>0)

{

cout << ” i= ”<<i<<”\n”;

i--;

}

Условие while(i>0) можно заменить на более лаконичное, но менее наглядное: while(i) .

 

А вот как с помощью оператора while можно распечатать строку символов:

int i=0;

char car[20]="abrakadabra";

while(car[i])

{

cout<<car[i];

i++;

}

Выполнение цикла прекратится, как только будет достигнут признак конца строки \0.При этом символы интерпретируются как целые в соответствии со значением их ASCII кода.

Цикл do while

Третьим типом цикла в С++ является цикл do while. Синтаксис цикла выглядит так:

do

Тело цикла

while (условие продолжение цикла); // обратите внимание

// на точку с запятой!

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

// в этом примере программа должна получить число до его проверки

#include <iostream.h>

Void main()

{

int n;

cout<<”Enter number in the range 1-10”;

do

{

cin>>n;

}

while(n!=7);

cout<<” 7 is my favorite number.\n”;

}

Операторы break и continue

Операторы break и continue позволяют программе пропустить фрагмент кода. В разделе 2.1.4 приводился пример использования break в операторе switch. Использование его в операторах цикла приводит к такому же эффекту – переходу к оператору, следующему за оператором цикла. Оператор continue используется в циклах и вызывает новую итерацию цикла. В приведенных ниже листингах показан вариант использования обоих операторов.

// в этом примере программа суммирует только четные числа.

// ноль – признак окончания ввода

#include <iostream.h>

Void main()

{

int n, sum=0;

cout<<" Enter integer number. To stop enter 0\n";

do

{

cin>>n;

if (n%2!=0)

Void main()

{

int x, y;

cout<<" Enter integer number. To stop enter 0\n";

do

{

cin>>n;

if (n==0)

break;

sum=sum+n;

}

while(n!=0);

cout<<" Sum="<<sum<<"\n";

}

 

Для всех видов циклов есть команды для прерывания цикла и для перехода к следующей итерации – это операторы break и continue, соответственно:

Ссылки и указатели.

В разделе 1.4 простые переменные определялись, как именованная область памяти, в которой хранятся данные. В процессе работы программа находит нужную переменную в памяти компьютера благодаря ее адресу. Узнать адрес переменной в С++ можно при помощи операции &.Например, если test – переменная, то &test определяет ее адрес. Следующий пример поясняет работу этой операции.

int cup = 4;

double nut = 6.5;

cout << “nut= ”<<nut;

cout << “and nut address= ”<<&nut<<’\n’;

cout << “cup= ”<< cup;

cout << “and cup address= ”<<&cup<<’\n’;

 

В результате выполнения программы на экране отобразится приблизительно следующее[3]:

nut = 6.5 and nut address = 0x0012FF7C

cup = 4 and cup address = 0x0012FF74

Как видим, при отображении адресов используется шестнадцатеричная система представления чисел. Разность между двумя адресами равно 8 и это имеет смысл, т.к. nut объявлена как тип doubleпод который отводится 8 байт.

При помощи знака & можно определить ссылку, которая по сути является синонимом имени переменной или вторым именем уже определенной переменной:

int first = 31; // объявили целочисленную переменную

int & second = first; // ссылка second – альтернативное имя first

cout<<second<<endl;

second=0; // изменили значение не только second

cout<<first; // что теперь будет выведено на экран?

Можно создать ссылку на константу:

const double & pi = 3.1415; // const указывает, что pi изменять нельзя

При работе со ссылками следует помнить следующие правила:

- при объявлении ссылка должна быть инициализирована (кроме случаев, когда она является параметром функции);

- после инициализации ссылке не может быть присвоена другая переменная;

- нельзя создавать массив ссылок, ссылки на ссылки, указатели на ссылки;

- тип ссылки должен совпадать с типом величины, на которую она ссылается.

Следующие примеры иллюстрируют ошибки, которые могут возникать при работе со ссылками:

Массивы и строки.

v Массив ‑ это совокупность однотипных элементов (int ,double,char и т.д.).

Для определения целочисленного массива в C/C++ надо написать:

int z[10]; //массив из 10 целых чисел

Общее форма для объявления массива:

typename arrayName[arraysize];

Здесь typename - тип элементов массива (double, float и т.д.), arrayName‑ имя массива, arraysize ‑задает число элементов массива и должно быть типа const, либо постоянным выражением, для которого все значения должны быть известны уже во время трансляции[4].

Ниже приведенный листинг показывает примеры верного и неверного объявления массивов.

int ar[3]; // объявлен целочисленный массив из 3 элементов

const int k=11; // объявлена целочисленная константа к

int n, m=4; // объявлены переменные типа целое

n=12;

double z[k],y[3*k]; // верное объявление массивов

double nz[n], ny[m]; // неверное объявление массивов

 

Элементы массивов в C/C++ всегда нумеруются с нуля. Таким образом, в приведенном в начале параграфа примере массив будет состоять из целочисленных элементов z[0], z[1], z[2], ...z[9]. Индекс внутри квадратных скобок позволяет обратиться к любому элементу массива. При объявлении массива можно сразу инициализировать его элементы:

double mass[3]={1.1, 11.24, 0.45};

Не будет ошибкой и такой вариант инициализации:

int arr[]={14, 0, 6, 12};

В этом случае компилятор самостоятельно подсчитает количество элементов объявленного массива.

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

int arr[]={14, 0, 6, 12}; // объявление и инициализация массива

int varr[4]; // объявление массива

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

{

varr[i] = 3*arr[i]; // в цикле происходит поэлементное

// присваивание массива varr

cout<<varr[i]<<’\t’; // возможен только поэлементный вывод

// значений массива

}

þ При обращении к элементам массива автоматического контроля границ массива не производится! Программа не запретит вам обратиться к элементу varr[-1] или varr[5]. Естественно, это приведет к ошибкам, часто с непредсказуемым результатом.

Многомерные массивы.

Для определения двумерного массива надо написать следующее выражение:

int z[3][4]; //массив из 12 целых чисел

Двумерный массив в С/С++‑ это массив массивов, т.е. каждый элемент массива z[0], z[1] и т.д. является указателем на одномерный массив. Двумерный массив располагается в памяти по строкам:

z[0] z[0] [0] z[0] [1] z[0] [2] z[0] [3]
z[1] z[1] [0] z[1] [1] z[1] [2] z[1] [3]
z[2] z[2] [0] z[2] [1] z[2] [2] z[2] [3]

 

Инициализация двумерного массива имеет свои особенности:

int a[3][3]={{11,12,13},{21,22,23},{31,32,33}};

Первый индекс нумерует строки, а второй – столбцы. Таким образом, a[0][1]=12, a[2][0]=31.

Многомерные массивы определяются подобно двумерным - какова размерность массива, столько пар квадратных скобок пишем. Такой формальный подход вполне приемлем, пока не столкнешься с необходимостью передачи многомерного массива в функцию.

þ Заметим, что понятие массивов в С/С++ тесно связано с указателями. Имя массива – это указатель на нулевой элемент массива. Таким образом, выражения arrи&arr[0] ‑ эквивалентны. Более подробно об этом будет сказано в разделе Динамическое определение массивов.

Двумерный массив хорошо моделирует математический объект – матрицу, поэтому используется дольно часто.

Строки

В языке С изначально не определен строковый тип данных. Вместо этого можно использовать так называемую С-строку – специально организованный массив символов.

þ Альтернативный способ описания строк в С++ появился вместе с классом string,нами он не рассматривается.

Инициализация строки может происходить так:

char s[100] = "пример строки";

или так:

char str[] = "объявление строки";

 

Неиспользуемым элементам массива s присваиваются специальные “нулевые” символы - \0. Так что в отличие от обычных массивов, конец строки можно найти по нулевому элементу. Так, последний символ строки s из предыдущего примера не ‘и’, а именно «нулевой символ» (не ноль, не пробел!)

Следующий листинг определяет длину строки по положению «нулевого» символа:

#include <iostream.h>

void main()

{

char st[]="0123456789";

cout<<st<<endl;//строку можно выводить целиком

int i=0;

while(st[i]!='\0')

i++;

cout<<i<<'\t'<<st[i];

}

На экран будет выведена строка 0123456789, затем число 10 (т.о. число элементов в символьном массиве 11), а последний, одиннадцатый символ на экране не отобразиться. Еще раз: строки всегда включают конечный нулевой символ, так что писать его при присвоении строки не требуется!

Для ввода-вывода строки используются потоковые объекты cin и cout, при этом посимвольный ввод-вывод, как для «обычных» массивов необязателен:

#include <iostream.h>

Void main()

{

const int len=80;

char st[len];

cin<<st; // строку можно вводить и

cout<<st<<endl;// выводить “целиком”

}

Проблема при вводе строк возникнет, если мы попытаемся ввести строку, состоящую из нескольких слов. Так как ввод выполняется до первого пробела, знака табуляции или символа конца строки ( \n ), то вместо двух (нескольких слов) будет введено только первое слово. Решение проблемы – воспользоваться методом getline:

#include <iostream.h>

Void main()

{ const int len=80;

char st[len];

Void main()

{

char st[80];

Void main()

{

fstream f("a.txt",ios::in||ios::nocreate);

char st[80],st2[]="test";

while(!f.eof())

{



Последнее изменение этой страницы: 2016-07-22

headinsider.info. Все права принадлежат авторам данных материалов.