Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Сборник задач и упражнений по языку Си.Стр 1 из 12Следующая ⇒
Руденко Т.В.
Сборник задач и упражнений по языку Си.
(учебное пособие для студентов II курса)
Москва 1999 УДК 519.682
Представлены задачи и упражнения по языку Си и программированию на нем. Рассматриваемая версия Си соответствует международному и ANSI-стандарту этого языка.
Сборник составлен как дополнение к учебнику Б. Кернигана, Д. Ритчи «Язык программирования Си» (М., «Финансы и статистика», 1992) и с учетом опыта преподавания программирования на факультете вычислительной математики и кибернетики МГУ.
Для студентов факультета ВМК в поддержку основного лекционного курса “Системное программное обеспечение” и для преподавателей, ведущих практические занятия по этому курсу.
Автор выражает благодарность сотрудникам кафедры алгоритмических языков за помощь и поддержку при создании этого сборника.
Рецензенты: доц. Машечкин И.В. доц. Терехин А.Н.
Руденко Т.В. “Сборник задач и упражнений по языку Си (учебное пособие для студентов II курса)”.
Издательский отдел факультета ВМиК МГУ (лицензия ЛР №040777 от 23.07.96), 1999.-80 с.
Печатается по решению Редакционно-издательского Совета факультета вычислительной математики и кибернетики МГУ им. М.В. Ломоносова
ISBN 5-89407-048-1
Ó Издательский отдел факультета вычислительной математики и кибернетики МГУ им. М.В.Ломоносова, 1999 ПРЕДИСЛОВИЕ
Сборник задач составлен как дополнение к учебнику Б. Кернигана и Д. Ритчи «Язык программирования Си» [1], поэтому в нем сохранен такой же порядок разделов. Однако предполагается, что некоторое минимальное представление о структуре программы на Си и простейшем вводе-выводе у читателя имеется (в объеме разделов 1.7 и 1.8 первой главы учебника по Си [1]). Сборник может быть использован и независимо от учебника Б. Кернигана и Д. Ритчи; рассматриваемая версия Си соответствует стандарту ANSI (X3.159 - 1989) [2]. Кроме того, в сборнике приведено краткое описание заданий практикума, которые рекомендуется выполнить для закрепления пройденного материала и получения навыков в написании законченных программ. Значительную часть сборника составляют приложения, где описана библиотека стандартных функций языка Си, некоторые системные функции ОС UNIX и фрагменты стандарта языка Си, связанные с правилами приведения типов и адресной арифметикой.
ТИПЫ, ОПЕРАЦИИ, ВЫРАЖЕНИЯ
2.1. Верно ли записаны константы, представляющие целочисленные значения? Для верно записанных констант определить их значение, тип. 123 1E6 123456789LU -5 0XFUL ‘0’ 058 ‘\x7’ 0X-1AD ‘\122’ 00123 0xffffffL 01A -‘x’ ²x² ‘a’U 0731UL ‘\n’ +0xaf 0X0
2.2. Верно ли записаны константы с плавающей точкой? Для верно записанных констант определить их значение, тип. 1.71 1E-6 0.314159E1F.005 0051E-04 5.E+2 0e0 0x1A1.5 05.5 0 0X1E6 0F 1234.56789L 1.0E-10D 3.1415U 1e-2f -12.3E-6 +10e6 123456L E-6
2.3. Верно ли записаны выражения? Для верно записанных выражений вычислить их значения (операции + - * / % =): int a, b, c, d, e; a = 2; b = 13; c = 7; d = 19; e = -4; b / a / c d / a % c c % d-e -e % a + b / a *-5+5 b % e 7-d%+(3-a) b % - e * c 9 / c - - 20 / d
2.4. Верно ли решена задача: «значение целочисленной переменной с увеличить на 1; целочисленной переменной а присвоить значение, равное удвоенному значению переменной с». int a, c; c = 5; a). c ++; b). a = 2 * c++; c). c += 1; d). a = c++ + c; a = 2 * c; a = c + c;
e). ++c; f). a = ++ c + c; g). a = c += 1 + c; h). a = (c+=1)+c; a = c + c;
2.5. Верно ли решена задача: «значение целочисленной переменной с уменьшить на 1; целочисленной переменной а присвоить значение, равное частному от деления переменной с на 2». int a, c; c = 5; a). -- c; b). a = -- c / 2; c). c -= 1; d). a = c -- / 2; a = c / 2; a = c % 2;
e). a = c -= 1/2; f). a = (c = c - 1)/2; g). a = (c -= 1)/2; h). a=(c-= 1)/2.0;
2.6. Эквивалентны ли выражения? a) E1 op= E2 и E1 = E1 op E2 b) E1 op= E2 и E1 = E1 op (E2) Замечание: здесь E1, E2 - выражения допустимого в этом случае типа; op - операция (одна из + - * / % >> << & ^ |).
2.7. Верно ли записаны выражения? Для верно записанных выражений вычислить их значения (операции + - * / ++ - - операции присваивания): int a, b, c; a = 2; b = 6; c = 3; - - - a -- - a b-- - a a += a ++ ++ b / a ++ * --c a --- b - a-- -b a ++ = b a = a ++ b++ / ++a * c -- - --a a- --c a ++ = a ++ a = b a = (b + 1) ++
2.8. Верно ли записаны выражения? Для верно записанных выражений вычислить их значения, определить тип результата (операции + - * / % ++ операции отношения, операции присваивания): int i, j, k, m; char c, d; i = 1; j = 2; k = -7; m = 0; c = ‘w’; d = ’a’+1 < c m = - i - 5 * j >= k+1 i + j++ + k = = -2*j m = 3 < j < 5 m = 3 = = j < 5 m = = c = ’w’ m = c!= 87 m = c =! 87 m =! c = 87 m =!c+87! m = =c + 87 m! = c + 87
k = = j - 9 = = i k *= 3 + j i + j =!k i += ++ j + 3 k %= m = 1 + n / 2 1 + 3 * n += 7 / 5 1 + 3 * (n += 7) / 5 c + i < c - ‘x’+10 i - k = = ‘0’+9 < 10
2.9. В логике справедливы утверждения: not (not x) = x x and true = x Верны ли соответствующие утверждения для операций! и && в Си? Ответ обосновать.
2.10. При любом вещественном y > 0 x < x + y математически верно. Верно ли подобное утверждение для выражения на Си?
2.11. Написать эквивалентное выражение, не содержащее операции! ! (a>b)! (2*a == b+4)! (a<b && c<d) ! (a<2 || a>5)! (a<1 || b<2 && c<3)
2.12. Пусть char c; short s; int i; unsigned u; signed char sc; float f; double d; long lng; unsigned short us; long double ld; Определить тип выражений: c - s / i u * 3 - 3.0 * u - i u - us * i (sc + d) * ld (5 * lng - ‘a’) * (s + u / 2) (f + 3) / (2.5f - s * 3.14)
2.13. Допустимо ли в Си? Если "да" - опишите семантику этих действий; если "нет" - объясните почему. а). ... b). ... int i; int a, b, m, n, z; i = (1 || 2) % (1 | 2); m = n = 5; printf (² i = %d\n², i); z = a = b = 0; z--, (a = b) = z + (m!= n); printf (²%d %d %d %d %d\n², a, b, m, n, z); с). ... d). ... int i = 1; double x = 1.9; int a; i = i << i | i; double b = 3.7; printf (² i = %d\n², i); a = b += (1 && 2 || 3)!= (int)x; printf (²%f %d %f\n², x, a, b); e). ... f).. .. int x; int i, x, y; x = 5; y = 10; i = 15; x = 5; ++ x =10; x = (y = 0, i = 1); printf ("%d\n", x); printf("%d %d %d\n", i, x,y); (x = y == 0), i=1; printf("%d %d %d\n", i, x, y); g). ... h). ... int x, y; int x = 2, y, z; x = 5; y = x && ++ x; x *= 3+2; x *= y = z = 4; printf("%d %d\n", x, y); printf ("%d %d %d\n", x, y, z); x = y == z; x == (y = z); printf ("%d %d %d\n", x, y, z); i). ... j). ... int x = 2, y = 1, z = 0; int x = 03, y = 02, z = 01; y = x && y || z; printf("%d\n", x | y & -z); x = x ||!y && z; printf("%d\n", x ^ y & -z); z = x / ++x; printf("%d\n", x & y && z); printf(" %d %d %d\n", x, y, z); printf("%d\n", x<<3); k). ... l). ... int x, y, z; x = y = z = 1; int x, y, z, i; x = y = z = 1; x += y += z; i = ++x || ++y && ++z; printf("%d\n", x < y? y++: x++); printf("%d%d%d%d\n", x,y,z,i); printf("%d\n", z+=x<y? ++x: y--); i = x++ <= --y || ++z >= i; printf("%d %d %d\n", x, y, z); printf("%d%d%d%d\n", x,y,z,i); printf("%d\n", z>=y && y>=x);
2.14. Что будет напечатано в результате выполнения следующего фрагмента программы? ... double d; float f; long lng; int i; short s; s = i = lng = f = d = 100/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); d = f = lng = i = s =100/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); s = i = lng = f = d = 1000000/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); d = f = lng = i = s =1000000/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); lng = s = f = i = d =100/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); f = s = d = lng = i = (double)100/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); s = i = lng = f = d = 100/(double)3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); f = s = d = lng = i = (double)100/3; printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d); i = s = lng = d = f = (double)(100/3); printf("s = %hd i = %d lng = %ld f = %f d = %f\n", s, i, lng, f, d);
2.15. Что будет напечатано в результате выполнения следующего фрагмента программы? double d = 3.2, x; int i = 2, y; x = (y = d / i) * 2; printf ("x = %f;y = %d\n", x, y); x = (y = d / i) * 2; printf ("x = %d;y = %f\n", x, y); y = (x = d / i) * 2; printf ("x = %f;y = %d\n", x, y); y = d * (x = 2.5 / d); printf ("x = %f; y = %d\n", x, y); x = d * (y = ((int)2.9 + 1.1) / d; printf ("x = %d y = %f\n", x, y);
2.16. Дано вещественное число x. Не пользуясь никакими операциями, кроме умножения, сложения и вычитания, вычислить 2x4-3x3+4x2-5x+6. Разрешается использовать не более четырех умножений и четырех сложений и вычитаний.
2.17. Целой переменной k присвоить значение, равное третьей от конца цифре в записи целого положительного числа x.
2.18. Целой переменной k присвоить значение, равное сумме цифр в записи целого положительного трехзначного числа x.
2.19. Целой переменной k присвоить значение, равное первой цифре дробной части в записи вещественного положительного числа x.
2.20. Определить число, полученное выписыванием в обратном порядке цифр заданного целого трехзначного числа.
2.21. Идет n-ая секунда суток. Определить, сколько полных часов и полных минут прошло к этому моменту.
2.22. Дано вещественное число x. Не пользуясь никакими операциями, кроме умножения, получить a) x21 за шесть операций b) x3 и x10 за четыре операции c) x5 и x13 за пять операций d) x2, x5 и x17 за шесть операций e) x4, x12 и x28 за шесть операций
2.23. Выражения, соединенные операциями && и ||, по правилам Си вычисляются слева направо; вычисления прекращаются, как только становится известна истинность или ложность результата. В других языках программирования, например в Паскале, вычисляются все части выражения в любом случае. Приведите «за» и «против» каждого из этих решений.
2.24. Почему в Си не допускается, чтобы один и тот же литерал-перечислитель входил в два различных перечислимых типа? Могут ли совпадать имена литералов-перечислителей и имена обычных переменных в одной области видимости? Могут ли разные литералы-перечислители иметь одинаковые значения?
2.25. «Упаковать» четыре символа в беззнаковое целое. Длина беззнакового целого равна 4.
2.26. «Распаковать» беззнаковое целое число в четыре символа. Длина беззнакового целого равна 4.
2.27. Заменить в целочисленной переменной x n бит, начиная с позиции p, n старшими инвертированными битами целочисленной переменной y.
2.28. Циклически сдвинуть значение целочисленной величины на n позиций вправо.
2.29. Циклически сдвинуть значение целочисленной величины на n позиций влево.
2.30. Выясните некоторые свойства и особенности поведения доступного Вам транслятора Си: a) выяснить, сколько байт отведено для хранения данных типа short, int, long, float, double и long double; b) выяснить способ представления типа char (signed- или unsigned- вариант); c) проконтролировать, все ли способы записи констант допустимы: · целых (обычная форма записи, u/U, l/L, их комбинации; запись констант в восьмеричной и шестнадцатиричной системах счисления) · вещественных (обычная форма записи, в экспоненциальном виде, f/F, l/L, e/E) · символьных (обычная форма записи, с помощью эскейп-последовательности) и строковых (в частности, происходит ли конкатенация рядом расположенных строковых констант) d) выяснить, как упорядочены коды символов '0' - '9', 'a' - 'z', 'A' - 'Z', пробел (между собой и относительно друг друга);
e) проконтролировать, происходит ли инициализация переменных по умолчанию; f) проверить, реагирует ли транслятор на попытку изменить константу; g) исследовать особенности выполнения операции % с отрицательными операндами; h) проверьте, действительно ли операции отношения == и!= имеют более низкий приоритет, чем все другие операции отношения; i) проверьте, действительно ли выполняется правило "ленивых вычислений" выражений в Си, т.е. прекращается ли вычисление выражений с логическими операциями, если возможно "досрочно" установить значение результата; j) проверьте, все ли виды операнда операции sizeof (X), определяемые стандартом для арифметических типов, допускаются компилятором; действительно ли выражение X не вычисляется.
УПРАВЛЕНИЕ Обработка числовых данных
Замечание: при решении некоторых задач этого раздела необходимы минимальные знания о «стандартном» вводе и выводе целых и вещественных чисел.
3.17. Для данных чисел a, b и c определить, сколько корней имеет уравнение ax2+bx+c = 0, и распечатать их. Если уравнение имеет комплексные корни, то распечатать их в виде v ± iw.
3.18. Подсчитать количество натуральных чисел n (111 £ n £ 999), в записи которых есть две одинаковые цифры.
3.19. Подсчитать количество натуральных чисел n (102 £ n £ 987), в которых все три цифры различны.
3.20. Подсчитать количество натуральных чисел n (11 £ n £ 999), являющихся палиндромами, и распечатать их.
3.21. Подсчитать количество цифр в десятичной записи целого неотрицательного числа n.
3.22. Определить, верно ли, что куб суммы цифр натурального числа n равен n2.
3.23. Определить, является ли натуральное число n степенью числа 3.
3.24. Для данного вещественного числа a среди чисел 1, 1 + (1/2), 1 + (1/2) + (1/3),... найти первое, большее a.
3.25. Для данного вещественного положительного числа a найти наименьшее целое положительное n такое, что 1 + 1/2 +1/3+... + 1/n > a.
3.26. Даны натуральное число n и вещественное число x. Среди чисел exp(cos(x2k))sin(x3k) (k = 1, 2,..., n) найти ближайшее к какому-нибудь целому.
3.27. Дано натуральное число n. Найти значение числа, полученного следующим образом: из записи числа n выбросить цифры 0 и 5, оставив прежним порядок остальных цифр.
3.28. Дано натуральное число n. Получить все такие натуральные q, что n делится на q2 и не делится на q3.
3.29. Дано натуральное число n. Получить все его натуральные делители.
3.30. Дано целое число m > 1.Получить наибольшее целое k, при котором 4k < m.
3.31. Дано натуральное число n. Получить наименьшее число вида 2r, превосходящее n.
3.32. Распечатать первые n простых чисел (p - простое число, если
3.33. Даны вещественные числа x и y (x > 0, y > 1). Получить целое число k (положительное, отрицательное или равное нулю), удовлетворяющее условию yk-1 £ x < yk.
3.34. Распечатать первые n чисел Фибоначчи (f0 = 1; f1 = 1; fk+1 = fk-1+ fk;
3.35. Вычислить с точностью eps > 0 значение «золотого сечения» - 0.5*(1+Ö5) - предел последовательности { qi }при i ® ¥ qi = fi / fi-1, i = 2, 3,...где fi - числа Фибоначчи (см. предыдущую задачу). Считать, что требуемая точность достигнута, если | qi-qi+1| < eps. 3.36. Распечатать числа Фибоначчи (см. задачу 3.34), являющиеся простыми числами со значениями меньше n.
3.37. Вычислить с точностью eps > 0 значение числа e - предел последовательности { xi }при i ® ¥ xi = (1+1/i)i, i = 1, 2,... Считать, что требуемая точность достигнута, если | xi-xi+1| < eps.
3.38. Вычислить значение å i! для i, изменяющихся от 1 до n. Воспользоваться соотношением å i! = 1 + 1*2 + 1*2*3 +...+ 1*2*3*...*n = 1+2*(1+3*(1+ +n*(1)...)).
3.39. Пусть a0 и b0 - положительные вещественные числа. Соотношениями an+1 = Ö(anbn); bn+1 = (an+bn) / 2 при n = 0, 1, 2,... задаются две бесконечные числовые последовательности {an}и {bn}, которые сходятся к общему пределу M(a0,b0), называемому арифметико-геометрическим средним чисел a0 и b0. Найти приближенное значение M(a0,b0) с точностью eps > 0. Поскольку при
3.40. Вычислить квадратные корни вещественных чисел x = 2.0, 3.0,..., 100.0. Распечатать значения x, Öx, количество итераций, необходимых для вычисления корня с точностью eps > 0. Для a > 0 величина Öa вычисляется следующим образом: a0 = 1; ai+1 = 0.5*(ai+a/ai ) i = 0, 1, 2,... Считать, что требуемая точность достигнута, если | ai-ai+1| < eps.
3.41. Найти приближенное значение числа p с точностью eps > 0. Для этого можно использовать представление числа 2/p в виде произведения корней Ö(1/2) *Ö(1/2+1/2Ö(1/2))*Ö(1/2+ 1/2Ö(1/2+1/2Ö(1/2)))*.... Вычисления прекращаются, когда два следующих друг за другом приближения для числа p будут отличаться меньше, чем на eps.
3.42. Для данного вещественного числа x и натурального n вычислить: a) sin x + sin2x +... + sinnx b) sin x + sinx2 +... + sinxn c) sin x + sin(sin x) +... + sin (sin (... sin(sin x)...))
3.43. Алгоритм Евклида нахождения наибольшего общего делителя (НОД) неотрицательных целых чисел основан на следующих свойствах этой величины: пусть m и n - одновременно не равные нулю целые неотрицательные числа и m ³ n. Тогда, если n = 0, то НОД(n, m) = m, а если n ¹ 0, то для чисел m, n, и r, где r - остаток от деления m на n, выполняется равенство НОД(m, n) = НОД(n, r). Используя алгоритм Евклида, определить наибольший общий делитель неотрицательных целых чисел a и b.
3.44. Вычислить 1 - 1/2 + 1/3 - 1/4 +...+1/9999 - 1/10000 следующими способами: a). последовательно слева направо; b). последовательно справа налево; c). последовательно слева направо вычисляются 1 +1/3 + 1/5 +... + 1/9999 и 1/2 + 1/4 +... + 1/10000, затем второе значение вычитается из первого; d). последовательно справа налево вычисляются 1 +1/3 + 1/5 +... + 1/9999 и 1/2 + 1/4 +... + 1/10000, затем второе значение вычитается из первого. Сравнить и объяснить полученные результаты.
3.45. Натуральное число называется совершенным, если оно равно сумме всех своих делителей, за исключением самого себя. Дано натуральное чис-
3.46. Определить, является ли число простых чисел, меньших 10000, простым числом.
3.47. Если p и q - простые числа и q = p+2, то они называются простыми сдвоенными числами или “близнецами” (twin primes). Например, 3 и 5 - такие простые числа. Распечатать все простые сдвоенные числа, меньшие N.
Обработка символьных данных
Замечание: при решении некоторых задач этого раздела необходимы минимальные знания о «стандартном» вводе и выводе литер.
3.48. Пусть во входном потоке находится последовательность литер, заканчивающаяся точкой (кодировка ASCII): a) определить, сколько раз в этой последовательности встречается символ ‘a’; b) определить, сколько символов ‘e’ предшествует первому вхождению символа ‘u’ (либо сколько всего символов ‘e’ в этой последовательности, если она не содержит символа ‘u’); c) выяснить, есть ли в данной последовательности хотя бы одна пара символов-соседей ‘n’ и ‘o’, т.е. образующих сочетание ‘n’ ‘o’ либо ‘o’ ‘n’; d) выяснить, чередуются ли в данной последовательности символы ‘+’ и ‘-‘, и сколько раз каждый из этих символов входит в эту последовательность; e) выяснить, сколько раз в данную последовательность входит группа подряд идущих символов, образующих слово С++; f) выяснить, есть ли среди символов этой последовательности символы, образующие слово char; g) выяснить, есть ли в данной последовательности фрагмент из подряд идущих литер, образующий начало латинского алфавита (строчные буквы), и какова его длина. Если таких фрагментов несколько, найти длину наибольшего из них. Если такого фрагмента нет, то считать длину равной нулю; h) выяснить, есть ли в данной последовательности фрагменты из подряд идущих цифр, изображающие целые числа без знака. Найти значение наибольшего из этих чисел. Если в этой последовательности нет ни одной цифры, то считать, что это значение равно нулю; i) определить, имеет ли данная последовательность символов структуру, которая может быть описана с помощью следующих правил: последовательность::= слагаемое + последовательность | слагаемое слагаемое::= идентификатор | целое идентификатор::= буква | идентификатор буква | идентификатор цифра буква::= A | B | C | D | E | F | G | H | I | J | K цифра::= 0 | 1 | 2 | 3 | 4 | 5 целое::= цифра | целое цифра
3.49. Пусть во входном потоке находится последовательность литер, заканчивающаяся точкой (кодировка ASCII). Вывести в выходной поток последовательность литер, измененную следующим образом: a) заменить все символы ‘?’ на’!’; b) удалить все символы ‘-‘ и удвоить все символы ‘&’; c) удалить все символы, не являющиеся строчными латинскими буквами; d) заменить все прописные латинские буквы строчными (другие символы копировать в выходной поток без изменения); e) заменить все строчные латинские буквы прописными (другие символы копировать в выходной поток без изменения); f) каждую группу рядом стоящих символов ‘+’ заменить одним таким символом; g) каждую группу из n рядом стоящих символов ‘*’ заменить группой из n/2 рядом стоящих символов ‘+’ (n >= 2); одиночные ‘*’ копировать в выходной поток без изменения; h) удалить из каждой группы подряд идущих цифр все начальные незначащие нули (если группа состоит только из нулей, то заменить эту группу одним нулем); i) удалить все комбинации символов the; j) оставить только те группы цифр, которые составлены из подряд идущих цифр с возрастающими значениями; все остальные цифры и группы цифр удалить (другие символы копировать в выходной поток без изменения); k) заменить все комбинации символов child комбинациями символов children; l) удалить группы символов, расположенные между фигурными скобками { и }. Скобки тоже должны быть удалены. Предполагается, что скобки сбалансированы, и внутри каждой пары скобок других фигурных скобок нет.
3.50. Пусть во входном потоке находится последовательность литер, заканчивающаяся маркером конца $ (кодировка ASCII). Вывести в выходной поток последовательность литер, измененную следующим образом: a) удалить из каждой группы подряд идущих цифр, в которой более двух цифр и которой предшествует точка, все цифры, начиная с третьей (например, a+12.3456-b-0.456789+1.3-45678 преобразуется в a+12.34-b-0.45+1.3-45678); b) удалить из каждой группы цифр, которой не предшествует точка, все начальные нули (кроме последнего, если за ним идет точка либо в этой группе нет других цифр, кроме нулей; например, a-000123+bc+0000.0008-0000+0001.07 преобразуется в a-123+bc+0.0008-0+1.07).
УКАЗАТЕЛИ И МАССИВЫ
5.1. Допустимо ли в Си? Если "да" - опишите семантику каждого правильного действия (не принимая во внимание ошибочные); если "нет" - объясните почему. a). ... int i,* p, j, *q; p = &i; q = &p; j = *p = 1; q = p-1; *p += 1; i = *++q + *p; q -= 1; i = *q ++ + *q; printf("i=%d, j=%d, *p=%d, *q=%d \n", i, j, *p, *q); b) ... int x = 1, y; char c = ‘a’; int *pi, *qi; char *pc; pi = &x; *pi = 3; y = *pi; *pi = c; qi = pi; pc = qi; *qi+=1; pi++; *(- - pi) = 5; y = *qi+1; pc = &c; ++*pc; (*pc)++; *pc++; *pc+=1; x = (int)pi; pi=(int*)pc; pi=(int*)x; x = 1+ *pi; pc=(char*)pi; c = *pc; pc = &y; x = qi – pi; qi = 0; qi+=pi; y = π y = (int)π pi = pi +5; *(pi+1)=0; pi=&(x+0);
5.2. К любому ли объекту в Си можно применять операцию взятия адреса &? 5. 3. Допустимо ли в Си? Если "да" - опишите семантику этих действий; если "нет" - объясните почему. a) int i = 2; const int j = 5; int *pi; const int *pci; int *const cpi; const int * const cpci; pi = &i; pci = &j; cpi = &i; cpci = &j; pci = &i; pi = (int*)&j; i = *pci + *pi; *pci = 3; *pi = 3; i=*pci++; *(cpi++)=5; *cpi++; b) int f(const int i, int j) { j++; return i+j; } main() { int a, b; const int c = 5; scanf("%d", &a); b = f(c,a); printf("a=%d, b=%d, c=%d \n", a, b, c); b = f(c,c); printf("a=%d, b=%d, c=%d \n", a, b, c); b = f(a,a); printf("a=%d, b=%d, c=%d \n", a, b, c); b = f(a,c); printf("a=%d, b=%d, c=%d \n", a, b, c); }
5.4. Пусть целочисленный массив a соддержит 100 элементов. Верно ли решена задача: "написать фрагмент программы, выполняющий суммирование всех элементов массива a". a) int a[100], sum, i; sum = 0; for (i = 0; i < 100; ++i) sum += a[i]; b) int a[100], *p, sum; sum = 0; for (p = a; p < &a[100]; ++p) sum = sum + *p; c) int a[100], *p, sum; sum = 0; for (p = &a[0]; p < &a[100]; p++) sum += *p; d) int a[100], sum, i; sum = 0; for (i = 0; i < 100; ++i) sum += *(a+i); e) int a[100], sum, i; sum = 0; for (i = 0; i < 100; ++a, ++i) sum += *a; f) int a[100], *p, sum, i; sum = 0; for (i = 0, p = a; i < 100; ++i) sum += p[i]; g) int a[100], *p, sum, i; sum = 0; for (i = 0, p = a; i < 100; ++i) sum += *(p+i);
5.5. Допустимо ли в Си? Если "да" - опишите семантику каждого правильного действия (не принимая во внимание ошибочные); если "нет" - объясните почему. a) ... int a[5] = { 1, 2, 3, 4, 5 }; int *p, x, *q, i; p = a + 2; * (p+2) = 7; *a += 3; q=*&p-1; x = ++ p - q ++; x += ++ *p; x=*p-- + *p++; for (i = 0; i < 5; i++) printf("a [%d]=%d", i, a[ i ]); printf("\n"); printf("x=%d, *p=%d, *q=%d \n", x, *p, *q); b) ... char *str = "abcdef"; char *p, *q, *r; int k; p = str; q = 0; p++; k = p - str; r = p+k; if (k && p || q) q = str + 6; p = q? r: q; *(p-1) = ‘a’; *r = ‘x’; printf("str: %s\n", str); c) ... char s[ ] = "0123456"; int *pi; char *pc1, *pc2; pc2 = s; pc1 = s + *(s+strlen(s) - 1) - ‘0’; pi = (int*) pc2; *pc1-- = ‘8’; if (pc1 - pc2 < 3) pc1 = pc2 = pi; else pc1 = (pc1+pc2)/2; if (s == pc2) *pc1 = *pc2 + 1; else *pc1 = ‘9’; printf("s: %s\n", s); d) ... int i; char *c; int *pi; i = ‘a’; pi = &i; c = (char*)pi + 3; printf("c1=%c", *c); i <<= 8; c--; printf("c2=%c\n", *c); e) ... char c1, c2; short i; char *pc; short *ps; c1 = ‘1’; c2 = ‘2’; ps =&i; pc = (char*)ps; *pc = c1; pc++; *pc = c2; printf("i = %hd\n", i);
5.6. Эквивалентны ли следующие фрагменты программы на Си? a[ i ] /= k+m и a[ i ] = a[ i ]/k+m a[ i ] /= k+m и a[ i ] = a[ i ]/(k+m) a[ i++]+=3 и a[i++] = a[ i++]+3 a[ i++]+=3 и a[ i ] = a[ i++]+3 a[ i++]+=3 и a[ i++ ] = a[ i ]+3 a[ i++]+=3 и a[ i ] = a[ i ]+3; i++;
5.7. Что напечатает следующая программа? #include <stdio.h> char str[ ] = "SSSWILTECH1\1\11W\1WALLMP1"; main() { int i, c; for (i = 2; (c = str [ i ])!= ‘\0’; i++) { switch (c) { case ‘a’: putchar(‘i’); continue; case ‘1’: break; case 1: while ((c = str [++ i ])!= ‘\1’ && c!= ‘\0’); case 9: putchar(‘S’); case ‘E’: case ‘L’: continue; default: putchar(c); continue; } putchar(‘ ’); } putchar(‘\n’); } 5.8. Что напечатает следующая программа? #include <stdio.h> int a[ ] = { 0, 1, 2, 3, 4 }; main() { int i, *p; for (i = 0; i <= 4; i++) printf("a[ i ]=%d ", a[ i ]); printf("\n"); for (p = &a[0]; p <= &a[4]; p++) printf("*p=%d ", *p); printf("\n"); for (p = &a[0], i = 0; i <= 4; i++) printf("p[ i ]=%d ", p[ i ]); printf("\n"); for (p = a, i = 0; p+i <= a+4; i++) printf("* (p+i)=%d ", * (p+i)); printf("\n"); for (p = a+4; p >= a; p--) printf("*p=%d ", *p); printf("\n"); for (p = a+4, i=0; i <= 4; i++) printf("p[ -i ]=%d ", p[ -i ]); printf("\n"); for (p = a+4; p >= a; p --) printf("a[ p - a ]=%d ", a[ p - a ]); printf("\n"); }
5.9. Что напечатает следующая программа? #include <stdio.h> int a[ ] = { 8, 7, 6, 5, 4 }; int *p[ ] = { a, a+1, a+2, a+3, a+4 }; int **pp = p; main() { printf("*a=%d **p=%d **pp=%d\n", *a, **p, **pp); pp++; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p, *pp-a, **pp); ++*pp; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p, *pp-a, **pp); pp = p; ++**pp; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p, *pp-a, **pp); }
5.10. Что напечатает следующая программа? #include <stdio.h> int a[ 3 ][ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; int *pa[ 3 ] = { a[ 0 ], a[ 1 ], a[ 2 ] }; int *p = a[ 0 ]; main() { int i; for (i = 0; i < 3; i ++) printf(" a[ i ][ 2 – i ]=%d *a[ i ]=%d *(*(a+i)+i)=%d\n", a[ i ][ 2 – i ], *a[ i ], *(*(a+i)+i)); for (i = 0; i < 3; i ++) printf("*pa[ i ]=%d p[ i ]=%d \n", *pa[ i ], p[ i ]); }
5.11. Что напечатает следующая программа? #include <stdio.h> char *c[ ] = { "ENTER", "NEW", "POINT", "FIRST" }; char ** cp[ ] = { c+3, c+2, c+1, c }; char ***cpp=cp; main() { printf("%s", **++cpp); printf("%s ", * -- *++cpp+3); printf("%s", *cpp[ -2 ]+3); printf("%s\n", cpp[ -1 ][ -1 ]+1); }
5.12. Какие соглашения о конце строки существуют в Си и Паскале? Укажите все «за» и «против» явного указания концов строк с помощью null-литеры ‘\0’.
5.13. В чем заключается проблема «висящей» ссылки? Приведите примеры. 5.14. Нужна ли в Си «сборка мусора»? Почему возникает такая проблема и как она решается в Си?
5.15. Прочитайте следующие описания и определения: int *ip, f(), *fip(), (*pfi)(); char *str[10]; char * (*cp)[5]; int (*r) (); double (*k)(double,int*); float * (* (*x) [6])(); double (* (* (y())[ ])(); int * (*const *name[9])(void); char * const p;
5.16. Определите переменную x как массив указателей на функцию, имеющую два параметра типа int и возвращающую результат типа указатель на double. 5.17. Определите переменную y как указатель на массив указателей на функцию без параметров, возвращающую результат типа указатель на функцию с одним параметром типа int и результатом типа float.
5.18. Что будет напечатано? Объяснить, почему результат будет таким. a) #include <stdio.h> b) #include <stdio.h> int try_to_change_it(int); void compare (int, int *); main() main() { int i = 4, j; { int i = 4, j = 5; j = try_to_change_it(i); compare(i, &j); printf("i=%d, j=%d\n", i, j); printf("i=%d, j=%d\n", i, j); } } int try_to_change_it(int k) void compare (int k, int *m) { printf("k1=%d\n", k); { printf("k1=%d,*m1=%d\n",k, *m); k+=33; k++; (*m)++; printf("k2=%d\n", k); printf("k2=%d,*m2=%d\n", k, *m); return k; } } 5.19. Верно ли решена задача: «Описать функцию, меняющую местами значения двух переменных символьного типа. Использовать эту функцию для изменения значений символьных переменных a и b.» a) void swap (char x, char y) b) void swap (char *x, char *y) { char t; t = x; x = y; y = t;} { char *t; t = x; x = y; y = t;} main() main() { char a,b; { char a,b; scanf("%c%c", &a, &b); scanf("%c%c", &a, &b); swap(a,b); swap(&a, &b); printf("a=%c,b=%c\n",a,b); printf("a=%c,b=%c\n",a,b); } } c) void swap (char *x, char *y) d) void swap (char *x, char *y) { char t; t = *x; *x = *y; *y = t;} { char t; t = *x; *x = *y; *y = t;} main() main() { char a,b; { char a,b; scanf("%c%c", &a, &b); scanf("%c%c", &a, &b); swap(a,b); swap(&a, &b); printf("a=%c,b=%c\n",a,b); printf("a=%c,b=%c\n",a,b); } } e) void swap (char x, char y) f) void swap (char &x, char &y) { char *t; t = &x; &x = &y; &y = t;} { char t; t = x; x = y; y = t;} main() main() { char a,b; { char a,b; scanf("%c%c", &a, &b); scanf("%c%c", &a, &b); swap(&a, &b); swap(a, b); printf("a=%c,b=%c\n",a,b); printf("a=%c,b=%c\n",a,b); } }
5.20. Допустимо ли в Си? Если "да" - опишите семантику этих действий; если "нет" - объясните почему. int ques (char *s1, char *s2) { while (*s1 && *s2 && *s1++ == *s2++); return *--s1 - *--s2; }
5.21. Допустимо ли в Си? Если "да" - опишите семантику этих действий; если "нет" - объясните почему. void ques (char *s1, char *s2, int n) { while (*s1 && *s2 && n-- && (*s1 ++ = *s2 ++)); }
5.22. Описать функцию, определяющую упорядочены ли строго по возрастанию элементы целочисленного массива из n элементов.
5.23. Описать функцию, определяющую индекс первого элемента целочисленного массива из n элементов, значение которого равно заданному числу x. Если такого элемента в массиве нет, то считать номер равным –1.
5.24. Описать функцию, вычисляющую значение x0 + x0*x1 + x0*x1*x2 + …+ x0*x1*x2 *… *xm, где xi - элементы вещественного массива x из n элементов, m - индекс первого отрицательного элемента этого массива либо число n-1, если такого элемента в массиве нет.
5.25. Описать функцию, вычисляющую значение max(x0 + xn-1, x1 + xn-2, x2 + xn-3,…, x(n-1)/2 + xn/2), где xi - элементы вещественного массива x из n элементов.
5.26. Описать функцию, вычисляющую значение min(x0 * x1, x1 * x2,
5.27. Описать функцию, вычисляющую значение x0*y0+x1*y1+ …+ xk*yk, где xi – отрицательные элементы вещественного массива a из n элементов, взятые в порядке их следования; yi – положительные элементы этого массива, взятые в обратном порядке; k = min(p,q), где p – количество положительных элементов массива a, q – количество отрицательных элементов этого массива.
5.28. Описать функцию, которая упорядочивает элементы целочисленного массива по неубыванию, используя следующий алгоритм сортировки: a) сортировка выбором: находится максимальный элемент массива и переносится в его конец; затем этот метод применяется ко всем элементам массива, кроме последнего (т.к. он уже находится на своем месте), и т.д. b) сортировка обменом (метод пузырька): последовательно сравни-ваются пары соседних элементов xk и x k+1 (k = 0, 1, …,n-2) и, если xk > x k+1, то они переставляются; в результате наибольший элемент окажется на своем месте в конце массива; затем этот метод применяется ко всем элементам, кроме последнего, и т.д. c) сортировка вставками: пусть первые k элементов массива (от 0 до
5.29. Описать функцию, определяющую индекс первого элемента целочисленного массива из n элементов, значение которого равно заданному числу x. Если такого элемента в массиве нет, то считать номер равным –1. Элементы массива упорядочены по возрастанию; использовать метод двоичного (бинарного) поиска.
5.30. Программа. Описать функцию f(a, n, p), определяющую, чередуются ли положительные и отрицательные элементы в целочисленном массиве a из n элементов и вычисляющую целочисленное значение p. Если элементы чередуются, то p - это сумма положительных элементов, иначе p - это произведение отрицательных элементов. С помощью этой функции провести анализ целочисленного массива x [50].
5.31. Программа. Описать функцию f(a, n, p), определяющую, упорядочены ли строго по возрастанию элементы в целочисленном массиве a из n элементов, и вычисляющую целочисленное значение p. Если элементы упорядочены, то p - это произведение разностей рядом стоящих элементов, иначе p - это количество нарушений порядка в массиве a. С помощью этой функции провести анализ целочисленного массива b [60].
5.32. Программа. Описать функцию f (s, n, x), определяющую, какой символ чаще других встречается в строке s и сколько раз он в нее входит. Если таких символов несколько, то взять первый из них по алфавиту. С помощью этой функции провести анализ строки str.
5.33. Программа. Описать функцию f(s, n, x), определяющую, какой символ реже других (но не нуль раз) встречается в строке s и сколько раз он в нее входит. Если таких символов несколько, то взять первый из них по алфавиту. С помощью этой функции провести анализ строки str.
5.34. Программа. Для целочисленного массива а, содержащего n элементов, описать функцию f(a, n, last, k, nlast), определяющую last - значение последнего из элементов массива а, значение которого принадлежит диапазону
5.35. Программа. Для вещественного массива а, содержащего n элементов, описать функцию G, определяющую значения максимального и минимального элементов этого массива. С помощью этой функции для вещественных массивов x[25] и y[40] вычислить соответствующие значения.
5.36. Описать функцию, которая изменяет заданную строку следующим образом: сначала записывает все элементы с четными индексами, а затем все элементы с нечетными индексами (с сохранением их относительного порядка в каждой группе). Например, abcdefgh => acegbdfh, vwxyz => vxzwy.
5.37. Описать функцию, которая в заданной строке меняет местами ее первую и вторую половины. Например, abcdefgh => efghabcd, vwxyz => yzxvw.
5.38. Описать функцию, осуществляющую циклический сдвиг на n позиций вправо элементов целочисленного массива, содержащего m элементов (n<m). 5.39. Описать функцию, осуществляющую циклический сдвиг на n позиций влево элементов целочисленного массива, содержащего m элементов (n<m). 5.40. Написать программу, обнуляющую каждую четную двоичную единицу в коде, размещенном в переменной типа int. Вывести исходные данные и полученный результат в виде, удобном для анализа проведенных преобразований. 5.41. Написать программу, обнуляющую каждую нечетную двоичную единицу в коде, размещенном в переменной типа int. Вывести исходные данные и полученный результат в виде, удобном для анализа проведенных преобразований.
|
|||||||||
Последнее изменение этой страницы: 2017-02-05; просмотров: 1341; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.142.197.198 (0.445 с.) |