В чем разница между этими двумя утверждениями, касающимися арифметики указателей? - PullRequest
3 голосов
/ 18 ноября 2011

В чем разница между

 char cur_byte=*((char *)(buf+i));

и

char *b=(char *)(buf);
char cur_byte=*(b+i);

Предположим: buf - указатель на void // void * buf;и я используется в качестве итератора в цикле for. Я нашел этот код (первую строку) в исходном коде переменного тока, который генерирует отпечатки пальцев rabin, и поскольку VC2010 express сообщил об этом как об ошибке, мне пришлось заменить его вторыми двумя строками.И я не уверен, может ли это сделать по назначению.Кроме того, я был бы признателен, если бы кто-нибудь дал мне подсказку, где взять работающий исходный код на C ++ для определения содержимого и формирования отпечатков пальцев.

Ответы [ 2 ]

5 голосов
/ 18 ноября 2011

В вашем первом утверждении вы добавляете целое число (i - это целочисленный тип, верно?) К void*, приводя к char* впоследствии. Арифметика указателей с пустыми указателями не определяется стандартом C , потому что компилятор не может знать, насколько он должен увеличивать указатель. Однако некоторые компиляторы определяют sizeof(void) == 1. В этом случае ваши два фрагмента эквивалентны, что объясняет, почему этот код мог работать с другим компилятором (спасибо Стиву Джессопу за указание на это) .

То, что вы имели в виду в своем первом фрагменте, было, вероятно, char cur_byte=*(((char *) buf) + i);, символ, указанный адресом, расположенный i символов после buf. * ​​1013 *

В следующей схеме, где i==4, cur_byte будет присвоено значение r.

Memory: |a| |w|o|r|d
         ^       ^
        buf     buf+i

В вашем втором утверждении:

char *b=(char *)(buf);
char cur_byte=*(b+i);

вы сначала назначаете buf на b, а затем назначаете содержимое b + i на cur_byte. b имеет тип char*, поэтому добавление i даст адрес i символов после b.

Memory: |a| |w|o|r|d|
         ^       ^
        buf         
         b      b+i

В конце эти два утверждения эквивалентны (за исключением присвоения b).

1 голос
/ 18 ноября 2011

Разница в выражениях (buf + i) против (b + i).

b имеет тип char*, поэтому (b + i) будет указывать на b + sizeof(char) * i.

buf может быть другого типа, поэтому (buf + i) будет указывать на buf + sizeof(BUFS_TYPE) * i.

...