Напишите функцию lower, которая переводит большие буквы в малые, используя условное выражение (а не конструкцию if-else).
Я буду вести этот блог в процессе чтения книги Брайана Кернигана и Денниса Ритчи "Язык программирования Си".
пятница, 21 ноября 2014 г.
Условные выражения
Инструкции
if (а > b)
z = a;
else
z = b;
пересылают в z большее из двух значений a и b. Условное выражение, написанное с помощью тернарного (т.е. имеющего три операнда) оператора ?:, представляет собой другой способ записи этой и подобных ей конструкций:
z = (a > b) ? а : b; /* z = max(a, b) */
выр1 ? выр2 : выр3
первым вычисляется выражение выр1. Если его значение не нуль (истина), то вычисляется выражение выр2 и значение этого выражения становится значением всего условного выражения. В противном случае вычисляется выражение выр3 и его значение становится значением условного выражения. Следует отметить, что из выражений выр2 и выр3 вычисляется только одно из них.
Условное выражение и в самом деле является выражением, и его можно использовать в любом месте, где допускается выражение.
Если выр2 и выр3 принадлежат разным типам, то тип результата определяется правилами преобразования, о которых шла речь ранее. Например, если f имеет тип float, a n — тип int, то типом выражения
(n > 0) ? f : n
будет float вне зависимости от того, положительно значение n или нет.
Заключать в скобки первое выражение в условном выражении не обязательно, так как приоритет ?: очень низкий (более низкий приоритет имеет только присваивание), но авторы книги рекомендуют всегда это делать, для лучшего восприятия.
В качестве примера приведится цикл, обеспечивающий печать n элементов массива по 10 на каждой строке с одним пробелом между колонками; каждая строка цикла, включая последнюю, заканчивается символом новой строки:
В качестве примера приведится цикл, обеспечивающий печать n элементов массива по 10 на каждой строке с одним пробелом между колонками; каждая строка цикла, включая последнюю, заканчивается символом новой строки:
#include <stdio.h>
int main(void)
{
int i, n;
char a[] = "C is a general-purpose programming language initially developed by Dennis Ritchie.";
n = sizeof(a);
for (i = 0; i < n; i++)
printf("%6d%c", a[i], (i % 10 == 9 || i == n - 1) ? '\n' : ' ');
return 0;
}
Символ новой строки посылается после каждого десятого и после n-го элемента. За всеми другими элементами следует пробел.
Еще один пример:
#include <stdio.h>
int main(void)
{
Символ новой строки посылается после каждого десятого и после n-го элемента. За всеми другими элементами следует пробел.
Еще один пример:
#include <stdio.h>
int main(void)
{
int n;
char a[] = "Привет, мир!";
n = sizeof(a);
printf("Вы имеете %d элемент%s.\n", n, (n % 10 == 1 && n % 100 != 11) ?
" " : ((n % 100 < 10 || n % 100 > 20) && n % 10 >= 2 && n % 10 <= 4) ?
"а" : "ов");
return 0;
}
Упражнение 2.9.
Применительно к числам, в представлении которых использован дополнительный код, выражение х &= (х-1) уничтожает самую правую 1 в х. Объясните, почему. Используйте это наблюдение при написании более быстрого варианта функции bitcount.
Операторы и выражения присваивания
Выражение
i = i + 2
в котором стоящая слева переменная повторяется и справа, можно написать в сжатом виде:
i += 2
Оператор +=, как и =, называется оператором присваивания.
Большинству бинарных операторов (аналогичных + и имеющих левый и правый операнды) соответствуют операторы присваивания ор=, где ор — один из операторов
+ * / % << >> & ^ |
Если выр1 и выр2 — выражения, то
выр1 ор= выр2
эквивалентно
выр1 = (выр1) ор (выр2)
с той лишь разницей, что выр1 вычисляется только один раз. Обратите внимание на скобки вокруг выр2:
x *= y + 1
эквивалентно
x = x * (y + 1)
но не
x = x * y + 1
В качестве примера авторы книги приводят функцию bitcount, подсчитывающую число единичных битов в своем аргументе целочисленного типа:
#include <stdio.h>
int bitcount(unsigned x);
int main(void)
{
printf("%u\n", bitcount(100));
return 0;
}
/* bitcount: подсчет единиц в х */
int bitcount(unsigned x)
{
int b;
for (b = 0; x != 0; x >>= 1)
if (x & 01)
b++;
return b;
}
Кроме того, в сложных выражениях вроде
yyval[yypv[p3 + p4] + yypv[p1 + p2]] += 2
благодаря оператору присваивания += запись становится более легкой для понимания, так как читателю при такой записи не потребуется старательно сравнивать два длинных выражения.
Присваивание вырабатывает значение и может применяться внутри выражения:
Типом и значением любого выражения присваивания являются тип и значение его левого операнда после завершения присваивания.
i = i + 2
в котором стоящая слева переменная повторяется и справа, можно написать в сжатом виде:
i += 2
Оператор +=, как и =, называется оператором присваивания.
Большинству бинарных операторов (аналогичных + и имеющих левый и правый операнды) соответствуют операторы присваивания ор=, где ор — один из операторов
+ * / % << >> & ^ |
Если выр1 и выр2 — выражения, то
выр1 ор= выр2
эквивалентно
выр1 = (выр1) ор (выр2)
с той лишь разницей, что выр1 вычисляется только один раз. Обратите внимание на скобки вокруг выр2:
x *= y + 1
эквивалентно
x = x * (y + 1)
но не
x = x * y + 1
#include <stdio.h>
int bitcount(unsigned x);
int main(void)
{
printf("%u\n", bitcount(100));
return 0;
}
/* bitcount: подсчет единиц в х */
int bitcount(unsigned x)
{
int b;
for (b = 0; x != 0; x >>= 1)
if (x & 01)
b++;
return b;
}
Независимо от машины, на которой будет работать эта программа, объявление аргумента x как unsigned гарантирует, что при правом сдвиге освобождающиеся биты будут заполняться нулями, а не знаковым битом.
yyval[yypv[p3 + p4] + yypv[p1 + p2]] += 2
благодаря оператору присваивания += запись становится более легкой для понимания, так как читателю при такой записи не потребуется старательно сравнивать два длинных выражения.
while ((с = getchar()) != EOF)
...
...
В выражениях встречаются и другие операторы присваивания (+=, -= и т.д.), хотя и реже.
Типом и значением любого выражения присваивания являются тип и значение его левого операнда после завершения присваивания.
среда, 19 ноября 2014 г.
Упражнение 2.8.
Напишите функцию rightrot(х, n), которая циклически сдвигает x вправо на n разрядов.
Упражнение 2.7.
Напишите функцию invert(х, р, n), возвращающую значение x с инвертированными n битами, начиная с позиции p (остальные биты не изменяются).
Упражнение 2.6.
Напишите функцию setbits(x, p, n, y), возвращающую значение x, в котором n битов, начиная с p-й позиции, заменены на n правых разрядов из y (остальные биты не изменяются).
Подписаться на:
Сообщения (Atom)