4. За всю дорогу я смог осилить лишь часть .
5. а. Хо Хо Хо! ! оХ оХ оХ
б. Указатель на char (т.е.char *)
в. Адрес начальной буквы X.
г. Выражение *--рс означает уменьшение указателя на 1 и использование значения, находящегося по этому адресу. —*рс означает взятие значения, на которое ссылается указатель рс, и уменьшение этого значения на 1 (например, символ X становится символом Ф).
д. Хо Хо Хо ! ! оХ оХ о
На заметку!
Между символами ! и ! присутствует нулевой символ, но обычно он не оказывает никакого
влияния на вывод.
е. while (* рс) проверяет, не указывает ли рс на нулевой символ (т.е. на конец строки). В выражении используется значение, расположенное по указанному месту.
while (рс - str) проверяет, не указывает ли рс на то же место, что и str (начало строки). В выражении применяются значения самих указателей.
ж. После первой итерации цикла while указатель рс указывает на нулевой символ. При входе во вторую итерацию цикла он указывает на ячейку памяти, предшествующую нулевому символу (т.е. расположенную непосредственно перед той, на которую указывает str). Этот байт интерпретируется как символ и выводится. Затем указатель возвращается к предыдущему байту. Условие выхода из цикла (рс == str) никогда не удовлетворяется, и процесс продолжается до тех пор, пока не будет прерван пользователем или системой.
з. рг() должен быть объявлен в вызывающей программе: char * pr(char *);
6. Под символьные переменные отводится один байт, поэтому sign занимает один байт. Но символьная констан та сохраняется в виде int, т.е. ‘$’ обычно будет использовать 2 или 4 байта; тем не менее, для хранения кода ‘$’ в действительности будет задействован только один байт из int. Строка "$" использует два байта: один для хранения кода символа ‘$’ и еще один для хранения кода символа ‘\0’.
7. Эта программа выводит следующие данные:
How are ya, sweetie? How are ya, sweetie?
Beat the clock, eat the clock.
Beat the clock. Win a toy.
Beat
chat
hat
at
814 Приложение А

8. Ее вывод имеет следующий вид:
faavrhee *le*on*sm
9. Ниже показано одно из возможных решений:
#include // для fgets() , getchar() char * s_gets(char * st, int n)
{
char * ret_val;
ret_val = fgets(st, n, stdin); if (ret_val)
{
while (*st != '\n' && *st != '\n') st + +;
if (*st == '\n')
* s t = '\0'); else
while (getchar() != '\n') continue;
}
return ret_val;
}
10. Вот одно из возможных решений:
int strlen(const char * s)
{
int ct = 0;
while (*s++) // или while (*s++ != '\n')
ct++;
return (ct);
}
11. Ниже показано одно из возможных решений:
#include // для fgets(), getchar()
#include // для strchr(); char * s_gets(char * st, int n)
{
char * ret_val; char * find;
ret_val = fgets (st, n, stdin); if (ret_val)
{
find = strchr(st, '\n'); // поиск символа новой строки
if (find) // если адрес не является NULL,
*find = '\0’; // поместить туда нулевой символ
else
while (getchar() != '\n') continue;
}
return ret_val;
}
Ответы на вопросы для самоконтроля 815
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. Статический класс хранения без связывания, статический класс хранения с внутренним связыванием и статический класс хранения с внешним связыванием.
Читать дальше