Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Сборник задач и упражнений по языку Си.Содержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте Руденко Т.В.
Сборник задач и упражнений по языку Си.
(учебное пособие для студентов 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. Вывести исходные данные и полученный результат в виде, удобном для анализа проведенных преобразований. 5.42. Описать функцию, которая в каждом элементе беззнако
|
||
|
Последнее изменение этой страницы: 2017-02-05; просмотров: 1528; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.10 (0.013 с.) |