Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Язык С не позволяет передавать весь массив целиком в качестве аргумента функции, но можно передать адрес массива. Функция затем может применять этот адрес для манипулирования исходным массивом. Если функция не предназначена для модификации исходного массива, то при объявлении формального параметра, представляющего массив, должно использоваться ключевое слово const. Внутри функции можно применять либо форму записи в виде массивов, либо форму записи в виде указателей. В любом случае на самом деле используется переменная типа указателя.
Добавление к указателю целого числа или инкрементирование указателя изменяет его значение на количество байтов, занимаемое в памяти объектом, на который ссылается указатель. То есть если pd указывает на 8-байтовое значение типа double в массиве, то добавление 1 к указателю pd увеличивает его значение на 8, так что указатель будет ссылаться на следующий элемент массива.
Двумерные массивы представляют массивы массивов. Например, объявление
double sales[5] [12];
создает массив по имени sales, имеющий пять элементов, каждый из которых является массивом из 12 значений типа double. На первый из этих одномерных массивов можно ссылаться как на sales [0], на второй — sales [1] и т.д., причем каждый из этих массивов содержит 12 значений double. Второй индекс служит для дос тупа к конкретным элементам в этих массивах. Например, sales [2] [5] — это шестой элемент массива sales [2], a sales [2] — третий элемент массива sales.
Традиционный для С метод передачи многомерного массива в функцию заключается в передаче имени массива, которое является адресом, параметру подходящего типа указателя. Объявление такого указателя должно описывать все размерности массива кроме первой; размерность первого параметра обычно передается во втором аргументе. Например, чтобы обработать ранее упоминавшийся массив sales, прототип функции и вызов функции должны иметь вид:
void display(double ar[][12], int rows);
display(sales, 5);
Массивы переменной длины предоставляют второй синтаксис, при котором обе размерности передаются функции в качестве аргументов. В этом случае прототип функции и вызов функции выглядят так:
void display(int rows, int cols, double ar[rows] [cols]);
display(5, 12, sales);
В обсуждении участвовали массивы значений типа int и типа double, но те же концепции применимы к массивам других типов. Тем не менее, в отношении символьных строк действует много специальных правил. Это вытекает из того факта, что завершающий нулевой символ в строке предоставляет функциям способ обнаружения конца строки без необходимости в передаче им размера. Символьные строки будут подробно рассматриваться в главе 11.
414 глава 10
Вопросы для самоконтроля
Ответы на вопросы для самоконтроля приведены в приложении А.
1. Что выведет следующая программа?
#include int main(void)
{
int ref[] = {8, 4, 0, 2 }; int *ptr; int index;
for (index = 0, ptr = ref; index < 4; index++, ptr++) printf("%d %d\n", ref[index], *ptr); return 0;
}
2. Сколько элементов содержит массив ref из вопроса 1?
3. Адресом чего является ref из вопроса 1? Что можно сказать oref + 1?На что указывает ++ref?
4. Каковы значения *ptr и * (ptr + 2) в каждом из следующих случаев?
а. int *ptr;
int torf [2] [2] = {12, 14, 16]; ptr = torf [0];
б. int * ptr;
int fort [2] [2] = { {12}; {14,16]]; ptr = fort[0];
5. Каковы значения **ptr и ** (ptr + 1) в каждом из следующих случаев?
а. int (*рtг) [2];
int torf[2] [2] = {12, 14, 16}; ptr = torf;
б. int (*ptr) [2];
int fort[2] [2] = { (12), {14,16] }; ptr = fort;
6. Предположим, что имеется следующее объявление:
int grid[30] [100];
а. Выразите адрес grid [22] [56] одним способом.
б. Выразите адрес grid [22] [0] двумя способами.
в. Выразите адрес grid[0] [0] тремя способами.
7. Создайте подходящее объявление для каждой из описанных ниже переменных.
а. digits представляет собой массив из 10 значений int.
б. rates представляет собой массив из шести значений float.
в. mat представляет собой массив, состоящий из трех массивов, каждый из которых содержит 5 целых чисел.
г. psa представляет собой массив, состоящий из 20 указателей на char.
д. pstr представляет собой указатель на массив, состоящий из 20 значений char.
Массивы и указатели 415
8. Решите перечисленные ниже задачи.
а. Объявите массив, состоящий из шести значений типа int, и инициализируйте его значениями 1,2, 4, 8, 16 и 32.
б. Используйте форму запись с массивом для представления третьего элемента (имеющего значение 4) массива, объявленного в пункте а).
в. Предполагая, что действуют правила С99/С11, объявите массив из 100 значений типа int и инициализируйте его таким образом, чтобы последний элемент получил значение -1; значения остальных элементов Moiyr быть произвольными.
г. Предполагая, что действуют правила С99/С11, объявите массив из 100 значений типа int и инициализируйте его так, чтобы элементы 5, 10, 11, 12 и 3 получили значение 101; значения остальных элементов могут быть произвольными.
9. Каков диапазон значений индекса в 10-элементном массиве?
10. Предположим, что имеются следующие объявления:
float rootbeer[10], things[10] [5], *pf, value = 2.2;
int i = 3;
Укажите, какие из приведенных ниже операторов допустимы, а какие — нет:
а. rootbeer [2] = value;
б. scanf ("%f", srootbeer);
в. rootbeer = value;
г. printf ("%f", rootbeer);
Д. things [4] [4] = rootbeer [3];
е. things [5] = rootbeer;
ж. pf = value;
з. pf = rootbeer;
11. Объявите массив размерности 800x600 значений типа int.
12. Имеются три объявления массивов:
double trots[20]; short clops[10][30]; long shots[5][10][15];
а. Напишите прототип и оператор вызова для традиционной функции типа void, которая обрабатывает массив trots, и для функции С, использующей массив переменной длины.
б. Напишите прототип и оператор вызова для традиционной функции типа void, которая обрабатывает массив clops, и для функции, использующей массив переменной длины.
в. Напишите прототип и оператор вызова для традиционной функции типа void, которая обрабатывает массива shots, и для функции, использующей массив переменной длины.
13. Имеются два прототипа функций:
void show(const double ar[], int n); // n - количество элементов
void show2(const double ar2[] [3], int n); // n - количество строк
а. Напишите вызов функции, который передает show() составной литерал, содержащий значения 8, 3, 9 и 2.
б. Напишите вызов функции, который передает show2() составной литерал, содержащий значения 8, 3 и 9 в первой строке и значения 5, 4 и 1 во второй ( троке.
416 глава 10
Упражнения по программированию
1. Модифицируйте программу rain, с из листинга 10.7, чтобы она выполняла вычисления с использованием указателей вместо индексов. (Вам по-прежнему придется объявлять и инициализировать массив.)
2. Напишите программу, которая инициализирует массив значений типа double и затем копирует его содержимое в три других массива. (Все четыре массива должны быть объявлены в главной программе.) Для создания первой копии воспользуйтесь функцией, в которой применяется форма записи с массивами. Для создания второй копии используйте функцию, в которой применяется форма записи с указателями и инкрементирование указателей. Первые две функции должны принимать в качестве аргументов имя целевого массива, имя исходного массива и количество элементов, подлежащих копированию. Третья функция должна принимать в качестве аргументов имя целевого массива, имя исходного массива и указатель на элемент, следующий за последним элементом в исходном массиве. С учетом приведенных ниже объявлений вызовы функций должны выглядеть так:
Читать дальшеИнтервал:
Закладка: