Не забывайте о классах памяти. Переменные можно определять вне функции; в этом случае их называют внешними (или глобальными) и они доступны более чем для одной функции. Переменные, определенные внутри функции, являются локальными для нее и не известны другим функциям. Если можно, используйте автоматическую разновидность локальных переменных. Они охраняют переменные одной функции от воздействия других функций.
ЧТО ВЫ ДОЛЖНЫ БЫЛИ УЗНАТЬ В ЭТОЙ ГЛАВЕ
Как представлять функцию: черный ящик с информационным потоком.
Что такое "проверка ошибок" и почему эта процедура хороша.
Алгоритм сортировки.
Как заставить функцию изменять массив: function(array).
Как преобразовать строку цифр в число.
Классы памяти: auto, extern, static и register.
Область действия каждого класса памяти.
Какой класс памяти использовать: обычно auto.
1. Что может сделать наш алгоритм сортировки неэффективным?
2. Как следует изменить нашу программу сортировки, чтобы она сортировала и по рядке возрастания, а не убывания?
3. Измените функцию print( ) таким образом, чтобы она печатала по 5 чисел в строке.
4. Как следует изменить функцию stoi( ), чтобы обрабатывать строки, представляющие восьмеричные числа?
5. Какие функции "знают" каждую переменную из описанных ниже? Есть ли здесь какие-нибудь ошибки?
/* файл1 */
int daisy;
main( )
{
int lily;
}
petal( ) {
extern int daisy, lily;
}
/* файл2 */
static int lily;
int rose;
stem( ) {
int rose;
}
root( )
{
extern int daisy;
}
1. Предположим, что вы сортируете 20 чисел. Программа производит 19 сравнений, чтобы найти одно самое большое число. Затем делается 18 сравнений, чтобы найти следующее самое большое. Вся информация, полученная во время первого поиска "забывается" за исключением самого большого числа, поставленного на первое место. Второе самое большое число можно временно поместить на место с номером 1, а затем при сортировке опустить вниз. Много сравнений, выполнявшихся в первый раз, повторяется второй, третий раз и т. д.
2. Замените array[search] > array[top] на array[search] < array[top]
3.
/* печать массива */
print(array, limit)
int array[ ], limit);
{
int index;
for(index = 0; index < limit; index++)
{ printf("%10d", array[index]);
if(index % 5 == 4) primf("\n" );
} printf("\n");
}
4. Во-первых, обеспечьте, чтобы разрешенные символы были только цифрами от 0 до 7. Во-вторых, умножайте на 8 вместо 10 каждый раз, когда обнаружите новую цифру.
5. daisy известна функции main( ) по умолчанию и функциям petal( ) и rоо1( ) благодаря extern-описанию. Она не известна функции stem( ), потому что они находятся в разных файлах.
Первая lily локальна для main: ссылка на lily в petal( ) является ошибочной, потому что в каждом из этих файлов нет внешней lily.
Есть внешняя статическая lity, но она известна только функциям второго файла. Первая, внешняя rose, известна функции root( ), а функция stem( ) отменила ее своей собственной локальной rose.
1. Некоторые пользователи, возможно испугаются, если их попросить ввести символ EOF.
а. Модифицируйте getarray( ) и вызываемые ею функции так, чтобы использовать символ # вместо EOF.
б. Модифицируйте затем их так, чтобы можно было использовать либо EOF, либо #.
2. Создайте программу, которая сортирует числа типа float.
3. Создайте программу, превращающую смешанный текст из прописных и строчных букв в текст, состоящий только из прописных букв.
4. Создайте программу, которая удваивает пробелы в тексте с одиночными пробелами.
11. Препроцессор языка Си
ДИРЕКТИВЫ ПРЕПРОЦЕССОРА СИМВОЛЬНЫЕ КОНСТАНТЫ МАКРООПРЕДЕЛЕНИЯ И "МАКРОФУНКЦИИ" ПОБОЧНЫЕ ЭФФЕКТЫ МАКРООПРЕДЕЛЕНИИ ВКЛЮЧЕНИЕ ФАЙЛОВ УСЛОВНАЯ КОМПИЛЯЦИЯ
ДИРЕКТИВЫ ПРЕПРОЦЕССОРА #define, #include, #undef, #if, #ifdef, #ifndef, #else, #endif
Язык Си был разработан в помощь работающим программистам, а им нравится его препроцессор. Этот полезный помощник просматривает программу до компилятора (отсюда и термин "препроцессор") и заменяет символические аббревиатуры в программе на соответствующие директивы. Он отыскивает другие файлы, необходимые вам, и может также изменить условия компиляции. Однако эти слова не отражают истинную пользу и значение препроцессора, поэтому обратимся к примерам. Конечно, до сих пор мы снабжали все примеры директивами #defineи #include, но теперь мы можем подытожить все, что изучили, и развить тему дальше.
Читать дальше