2014-09-22 5 views
0

Во многих решениях для codechef для более быстрого ввода данных я сталкивался с этим выражением, но я не могу понять это выражение, поскольку у меня нет большого опыта.Каков фактический смысл этого выражения: n = (n << 3) + (n << 1) + ch-'0 ', ch = getchar_unlocked();

inline int scan() { 

int n=0; 

int ch=getchar_unlocked(); 

while(ch <48)ch=getchar_unlocked(); 

while(ch >47) 

n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked(); 

return n; 

} 

В приведенной выше функции, что цель указанной ниже выражения

n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked(); 

и каков смысл (п < < 3) + (N < < 1)

+0

все отвечает тривиальной часть с << а как насчет «» части в этой строке это синтаксическая ошибка? –

+4

Урок здесь не в использовании кодека для поиска хорошего кода. –

+0

@callmecarrot - «,» является оператором запятой. Из K & R: «Пара выражений, разделенных запятой, оценивается слева направо, а значение левого выражения отбрасывается. Тип и значение результата - это тип и значение правого операнда». В основном, они использовали оператор запятой, чтобы избежать размещения фигурных скобок вокруг тела цикла while. Я должен согласиться с OliverCharlesworth, если вы ищете хороший код, избегайте кодека. – user3386109

ответ

0

Если входной поток состоит из символов 0-9, то блок кода

while(ch >47) 
    n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked(); 

вычисляет десятичное целое число из строки до тех пор, пока ch < 58, то есть '9'. Если ch >= 58, результат нечувствителен.

Предположим, что первый символ при вводе цикла - 8. Затем

n = (n<<3)+(n<<1) + ch-'0' = 8 

Скажем, второй символ 5. Затем

n = (n<<3)+(n<<1) + ch-'0' = 85 

и так далее.

0

n<<3 средств n сдвинут на 3 бит влево и n<<1 означает, что n сдвинут на 1 бит влево, а затем значение ASCII 0 вычитается из ch, чтобы получить фактическое число в int.

Пример: когда n=2 и n 1 бит сдвинут влево, он станет 4. Поскольку двоичное представление 2 равно 010, и когда он сдвигает 1 бит влево, он становится 100, который является двоичным представлением 4. Он работает одинаково для n<<3.

+0

Я думал написать тот же ответ, но потом я заметил «,» в этой строке .. так что я не уверен, что это синтаксическая ошибка? –

+0

нет, это не синтаксическая ошибка. –

0

<< - оператор сдвига влево, который легко найти в любых учебных пособиях. Просто зайдите в список операторов Google и посмотрите.

(n << 3) + (n << 1) = n*8 + n*2 = n*10 

Это старая оптимизация трюк, но, вероятно, не будет столь же эффективным, как и прежде, в современных архитектурах с быстрыми мультипликаторами

+2

Это бесполезная оптимизация; хороший компилятор сделает одно и то же преобразование (или даже лучше), если это действительно полезно для машины, на которую вы нацеливаетесь. –

0

Оператор запятой разделяет два выражения. Первое оценивается, а затем отбрасывается, а затем оценивается второе (и это значение может быть использовано). Оператор запятой имеет более низкий приоритет, чем присваивания, так что интерпретация, как уже говорили другие

n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked();

умножить на 10 л, добавить значение ч это смещение от 0, и сохранить результат в п. Затем вызовите getchar_unlocked() и присвойте возвращаемое значение ch. Запятая не делает ничего, кроме добавления путаницы в код здесь. Было бы лучше использовать два утверждения.

Я никогда не видел, чтобы оператор запятой использовался вне инициализации/приращения цикла, но он удобен там.

for (count = 0, index = 1; index < MAX_INDEX; count += 1, index += 2) { /* some code */ }