2017-01-20 4 views
0

У меня есть несколько вопросов, которые понимают оператор сдвига влево. Я знаю, что если сдвиг на х количество бит влево, поэтому довольно много умножает число на 2 на мощность числа сдвинутых битов.Нужна помощь в понимании оператора левого сдвига в C

Но рассмотрим эту программу:

int a=4,*pA=&a,r3; 
printf("%d\n",pA); 
printf("%d\n",(*pA<<2)); 
r3=pA-(*pA<<2); 
printf("%d",r3); 

Он печатает мкА, и (* пА < < 2) отдельно, и если вы должны были вычесть эти два, он не будет равно r3 написано в выражение, выключенное в 4 раза, которое является размером int. Но где вам нужно учитывать размер int, так как у вас есть как pA, так и (* pA < < 2), а их вычитание не соответствует тому, что должно быть.

Любая помощь приветствуется ...

Для записи, я не заинтересован в распечатке фактическое значение указателя, но на самом деле его адрес сдвигается на 2 бита. И я не понимаю точного процесса, который происходит.

+0

Что это, чего вы ожидали? – Downvoter

+0

Для a = 4, pA появляется как 2686724, а * pA << 2 - 80. Но r3 появляется как 2686404, а не 2686644. – Radu

+0

'pA' - указатель. Вы печатаете адрес указатель. Чтобы напечатать фактическое значение, вам нужно будет разыменовать его. – tambre

ответ

5

Арифметика на шкале указателя с размером, на который указывает. Итак, когда вы делаете pA - 80 ваш код на самом деле делает pA - 80*sizeof(*pA). Это не имеет никакого отношения к <<.

Также вы должны печатать адреса, используя спецификатор формата %p. И для хранения значений указателя в целочисленном типе используйте intptr_t или uintptr_t (от stdint.h). Включите предупреждения в своем компиляторе, и он должен пожаловаться, если вы этого не сделаете.

+0

Делает больше всего смысла. Спасибо. – Radu

1

Оператор разыменования * имеет более высокий приоритет, чем оператор сдвига влево <<. Таким образом, выражение *pA<<2 фактически оценивает значение (*pA)<<2. Это даст вам значение указал на по pA, т.е. a влево сдвинут на 2.

Похоже, что вы хотите pA<<2, однако указатель не является допустимым операнд оператора <<. Умножение значения указателя не определено и не имеет смысла. Однако вы можете добавить или вычесть из указателя.

Оператор индекса [] является синтаксическим сахаром вокруг добавления указателя и разыменования, поэтому вы можете использовать его. Однако pA указывает на один int, а не на массив, так что это undefined behavior.

+0

Нет, я действительно хочу, чтобы это было смещено на (* pA) << 2. – Radu

+1

@Radu Это то, что вы делаете сейчас, т. Е. Смещение значения не указателя. Смещение указателя бессмысленно. – dbush

Смежные вопросы