Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
12. Одно из возможных решений выглядит так:
#include /* для определения NULL */
char * strblk(char * string)
{
while (*string !='' && *string != '\n')
string++; /* остановиться на первом пробеле или нулевом
символе */
if (*string == '\0')
return NULL; /* NULL - это нулевой указатель */
else
return string;
}
Второе решение предотвращает изменение строки функцией, но позволяет применять возвращаемое значение для изменения строки. Выражение (char *) string называют “избавлением от const”.
#include /* для определения NULL */
char * strblk(const char * string)
{
while (*string !=''&& *string != '\0')
string++; /* остановиться на первом пробеле или нулевом символе */ if (*string == '\0')
return NULL; /* NULL - это нулевой указатель */
else
return (char *) string;
}
13. Ниже показано возможное решение:
/* compare.с -- это будет работать */
#include
#include // объявление strcmp() #include
#define ANSWER "GRANT"
#define SIZE 40
char * s_gets(char * st, int n); void ToUppertchar * str);
int main(void)
{
char try[SIZE];
puts("Кто похоронен в могиле Гранта?"); s_gets(try, SIZE);
ToUpper (try);
while (strcmp(try,ANSWER) != 0)
{
puts("Неправильно! Попытайтесь еще раз."); s_gets (try, SIZE);
ToUpper (try);
}
puts ("Теперь правильно!"); return 0;
}
816 Приложение А
void ToUpper(char * str)
{
while (*str != '\0')
{
*str = toupper(* s tr); str++;
}
}
char * s_gets(char * st, int n)
{
char * ret_val; int i = 0;
ret_val = fgets(st, n, stdin); if (ret_val)
{
while (st [i] != '\n' && st [i] != '\0') i + +;
if (s t [i] == '\n') st[i] = '\0';
else // требуется наличие words [i] == '\0' while (getchar() != '\n') continue;
}
return ret_val;
}
Ответы на вопросы для самоконтроля из главы 12
1. Автоматический класс хранения, регистровый класс хранения и статический класс хранения без связывания.
2. Статический класс хранения без связывания, статический класс хранения с внутренним связыванием и статический класс хранения с внешним связыванием.
3. Статический класс хранения с внешним связыванием. Статический класс хранения с внутренним связыванием.
4. Они не имеют связывания.
5. Ключевое слово extern используется в объявлениях для указания переменной или функции, которая объявлена в каком-то другом месте.
6. Оба оператора выделяют память под массив из 100 значений int. Оператор, в котором используется calloc(), дополнительно устанавливает каждый элемент в 0.
7. Переменная daisy известна функции main() по умолчанию, а функциям petal(), stem() и root() — благодаря объявлению extern. Объявление extern int daisy; во втором файле делает переменную daisy известной всем функциям в этом файле. Первая переменная lily является локальной для функции main(). Ссылка на переменную lily в функции petal() — ошибка, поскольку ни один из файлов не содержит объявления внешней переменной lily. Существует внешняя статическая переменная lily, но она известна только функциям из второго файла. Первая внешняя переменная rose известна функции root(), но функция stem() заменяет ее собственной локальной переменной rose.
Ответы на вопросы для самоконтроля 817
8. Вывод будет следующим:
color в main() равно В color в first() равно R color в main() равно В color в second() равно G color в main() равно G
Функция first() не использует глобальную переменную color, но ее использует функция second().
9. а. Они говорят о том, что программа будет использовать переменную plink, ко
торая локальна для файла, содержащего функцию. Первый аргумент функции value ct() — это указатель на целочисленное значение, которое, по всей видимости, является первым элементом массива, состоящего из n членов. В данном случае важно отметить, что программа не сможет применять указатель arr для изменения значений в исходном массиве,
б. Нет. Аргументы value и n уже являются копиями исходных данных, поэтому функция никак не может изменять соответствующие значения в вызывающей программе. Эти объявления предотвращают изменение значений value и п внутри самой функции. Например, функция не могла бы использовать выражение n++, если бы объявление n было снабжено const.
Ответы на вопросы для самоконтроля из главы 13
1. Программа должна содержать строку t#include , чтобы можно было использовать определения этого файла. Переменная fp должна быть объявлена как файловый указатель: FILE *fp;. Функция fopen() требует указания режима: fopen ("gelatin", "w") или, возможно режима "а". Порядок следования аргументов функции fputs() должен быть обратным. Для повышения удобочитаемости строка вывода должна иметь символ новой строки, поскольку fputs() не добавляет его автоматически. Функция fclose() требует передачи в качестве аргумента файлового указателя, а не имени файла: fclose(fp;. Ниже показана скорректированная версия:
#include int main(void)
{
FILE * fprint k;
fp = fopen("gelatin", "w"); for (k = 0; k < 30; k+ + )
fputs("Кто-то ест студень.\n", fp); fclose(fp);
return 0;
}
2. По возможности она будет открывать файл, имя которого задано в первом аргументе командной строки, и выводить на экран каждый присутствующий в файле цифровой символ.
818 Приложение А
3 а. ch = getc (fpl);
б. fprintf(fp2,"%c"\n",ch);
в. putc (ch, fp2);
г. fclose (fpl); /* закрыть файл terky */
На заметку!
Указатель fpl используется для операций ввода, поскольку он идентифицирует файл, открытый в режиме чтения. Подобным же образом файл, на который указывает fp2, был открыт в режиме записи, поэтому он применяется с функциями вывода.
4. Ниже демонстрируется один из подходов:
#include
#include
int main(int argc,char * argv[])
{
FILE * fp; double n; double sum = 0.0; int ct = 0;
if (argc == 1) fp = stdin; else if (argc == 2)
{
if ((fp = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "He удается открыть %s\n", argv[l]); exit(EXIT_FAILURE);
}
}
else
{
fprintf(stderr, "Использование: %s [имя_файла]\n", argv[0]); exit(EXIT_FAILURE);
}
while (fscanf(fp, "%lf", &n) == 1)
{
sum += n;
++ct;
}
if (ct > 0)
printf("Среднее арифметическое %d значений = %f\n", ct, sum / ct); else
printf("Допустимые данные отсутствуют.\n"); return 0;
}
5. Одно из возможных решений выглядит так:
#include
#include
#define BUF 256
int has_ch(char ch, const char * line);
Ответы на вопросы для самоконтроля 819
int main(int argc,char * argv[])
{ ‘
FILE * fp; char ch;
char line [BUF]; if (argc != 3)
{
printf("Использование: %s символ имя_файла\n", argv[0]); exit(EXIT_FAILURE);
}
ch = argv[1][0];
if ((fp = fopen(argv[2] , "r")) = NULL)
{
printf("He удается открыть %s\n", argv[2]); exit(EXIT_FAILURE);
}
while (fgets(line,BUF,fp) != NULL)
{
if (has_ch(ch,line)) fputs(line,stdout);
}
fclose(fp); return 0;
}
int has_ch(char ch, const char * line)
{
while (*line)
if (ch = *line++) return(1); return 0;
}
Функции fgets() и fputs() работают вместе, поскольку fgets() оставляет в строке символ новой строки \n, созданный в результате нажатия клавиши , а функция fputs() не добавляет его, как это делает puts().
6. Отличие между двоичным и текстовым файлами определяется системнозависимыми особенностями этих файловых форматов. Отличие между двоичным и текстовым потоками связано с преобразованиями, выполняемыми программой во время чтения или записи потоков. (В двоичном потоке преобразования не делаются; в текстовом потоке могут осуществляться преобразования символов новой строки и других символов.)
7. а. Сохранение числа 8238201 с помощью функции fprintf() приводит к его со
Читать дальшеИнтервал:
Закладка: