Как это преобразование может работать в C? - PullRequest
0 голосов
/ 09 июля 2011

Я хочу, чтобы значение int второго символа в строке; НЕ значение ASCII, только то, что там хранится.

int strLen = 0;  
char str[] = { 'b', 3, 'd', 'e', 'f' };   

strLen = strLen | *(str + 1);    

/* this prints 3; it's OK */
printf("strLen => %d\r\n", strLen);    

Теперь получим значение второго символа, равное 3, а также значение 'b', равное 98, так что в итоге я получу что-то отличное от 3, чего я и хочу.

Однако это тоже работает, и результат все еще 3:

strLen = *(str + 1);

printf("strLen => %d\r\n", strLen);  

Кто-нибудь может объяснить, почему?

Ответы [ 3 ]

4 голосов
/ 10 июля 2011

Делая догадку о недопонимании ядра здесь, я хочу сосредоточиться на сокращенной части кода здесь:

int strLen = 0;  
char str[] = { 'b', 3, 'd', 'e', 'f' }; 
strLen = *(str + 1);

Последняя строка - это задание.Правая сторона (*(str + 1)) имеет тип char.Левая сторона - int.То, что компилятор при назначении маленького целочисленного типа большому - это просто выразить значение маленького типизированного выражения в большем типе.1012 *

3 голосов
/ 10 июля 2011

Битовое или что-то с нулем даст вам исходный результат:

x | 0 == x

Получено strlen = 0

strLen | *(str + 1) == *(str + 1)

Добавление битового провода или ничего не делает,поэтому оба ваших примера в точности эквивалентны, поэтому, конечно, они дают одинаковый результат.Непонятно, почему вы кладете битовый код или вообще туда в первом случае, в любом случае, это не имеет смысла.

В любом случае любая отмена ссылки на str (включая любое ее добавление),поскольку это символ *, он всегда будет символом - это один символ.* (str) == 'b', * (str + 1) == 3, * (str + 2) == 'd' и т. д. Если вы хотите получить более двух символов из массива, просто получитедва символа:

printf("%d %d\r\n", *str, *(str+1)); 
2 голосов
/ 10 июля 2011

На этот вопрос сложно ответить, потому что трудно определить, какая у вас ментальная модель ситуации.

Мне нужно значение int второго символа в строке;НЕ значение ASCII, только то, что там хранится.

Доступ к значению, хранящемуся во втором символе в строке, осуществляется через str[1] или *(str + 1) или, возможно, *++str.Результатом является значение, хранящееся в строке.В вашей примерной строке значение равно 3;этот символ также известен как CONTROL-C .Это отличается от значения, которое будет храниться там для цифры «3»;обычно он хранится как 51 (при условии, что кодовая страница основана на стандарте ISO 8859-1 или одном из его близких родственников, который использует такое же распределение символов, что и ASCII).

strLen = 0;, а затем strLen = strLen | *(str + 1);достичь того же результата, что и:

strLen = str[1];
strLen = *(str + 1);

В обоих случаях strLen теперь содержит значение 3.

Затем оператор печати преобразует целочисленное значение 3 в строку, содержащую:

strLen => 3

, за которыми следуют CR и LF.(CR не требуется, даже на компьютере с Windows. Однако это отклоняет от рассматриваемой проблемы.)

Эти символы затем отправляются на стандартный вывод.Обратите внимание, что значение в позиции 10 на выходе (считая от нуля) совпадает с '3', обычно 51, и отличается от значения 3, хранящегося в строке.Ваш формат запросил это преобразование.Если вы хотите напечатать символ, вы говорите так:

printf("strLen => %c\n", strLen);

Это выведет CONTROL-C на выход;как это будет выглядеть, зависит от вашего драйвера терминала и настроек терминала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...