Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка-ТП-С++.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
661.5 Кб
Скачать

5.1.6. Ошибки при передаче по адресу

Посмотрите на следующую программу и найдите, что здесь неправильно:

void main()

{

int a, b, sum;

printf("Введите два значения:");

scanf("%d %d", a, b);

sum = a + b;

printf("Сумма значений равна: %d\n", sum);

}

Нашли? Ошибка в операторе

scanf("%d %d", a, b);

Вспомните, что scanf требует от вас передачи адресов, а не значений!

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

Правильно этот оператор необходимо записать так:

scanf(“%d %d”, &a, &b);

Здесь функции scanf передаются адреса a и b, и введенные значения правильно запоминаются в этих переменных по их адресам.

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

Что произойдет, если вы вызовете ее следующим образом:

void main()

{

int i,j;

i = 42;

j = 53;

printf("До обработки: i = %fd j = %fd\n", i, j);

swap(i, j);

printf("После обработки: i = %fd j = %fd\n", i, j);

}

Переменные i и j будут иметь одни и те же значения как до, так и после их обработки путем обращения к функции swap; однако значения адресов чисел 421 и 53 будут переставлены, что породит некоторые хитрые и труднообнаружимые ошибки. Как избежать этого?

Пользуйтесь прототипами функций и полными определениями функций.

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

void swap(a, b)

int *a, *b;

{

}

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

5.2. Массивы

Большинство языков высокого уровня – включая С++ – позволяют определять МАССИВЫ, т.е. индексированный набор данных определенного типа. Используя массив, вы можете переписать предыдущую программу следующим образом:

void main()

{

#define NUMINTS 3

int list[NUMINTS], i;

list[0] = 421;

list[1] = 53;

list[2] = 1806;

printf("Список адресов:");

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

printf("%p ",&list[i]);

printf("\nСписок значений: ");

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

printf("%4p ", list[i]);

printf("\n");

}

Выражение int list[NUMINTS] объявляет list как массив переменных типа int, с объемом памяти, выделяемым для трех целых переменных.

К первой переменной массива можно обращаться как к list[0], ко второй – как к list[1], и третьей как к list[2].

В общем случае описание любого массива имеет следующий вид:

Type name[size]

(тип имя[размер]),

где: type – тип данных элементов массива (любой из допустимых в языке);

name – имя массива.

Первый элемент массива – это name[0], последний элемент – name[size-1]; общий объем памяти в байтах определяется выражением size*(sizeof(nype)).