2013-08-16 3 views
1

Что касается вопроса Why do I have to specify data type each time in C? и моего предыдущего вопроса how to read memory bytes one by one in hex(so without any format) with printf()размера форматировщик в Е()

Можно ли уточнить ниже вопрос для меня?

int32_t a[3]={21,3,1000031}; 
char* p1=&a[0]; /* char is 1-bye and &a[0] is 0x0004 for example */ 

printf("p1 in hex=%x\n",*p1); /* 4 bytes starting from word-aligned address p1 */ 
printf("(p1+3)=%d",(p1+3)); /* 4 bytes starting from a NON word-aligned address?* line 2 printf */ 
printf("p1+3=%p",p1+3) /* line 3 print*/ 

% х и% d ВСЕГДА Телль Printf использовать формат INT, который в моем компьютере является 4 байта? я прав?

(p1 + 3) не является слово выровнен адрес Ox004 + 3 = 0x007, так что же PRINTF() показывают в этом случае? По-другому, какие байты обеспокоены линии 2 Printf?

также,% p formatter (void *) нужен ли 1 байт для чтения (из-за символа) или поскольку мы говорим о указателях, и они всегда принимают 4 байта (одно слово)?

Чтобы подвести итоги,% d% x% p, .. они читают постоянный размер (в зависимости от ПК) из памяти или зависит от размера соответствующих аргументов?

+0

'printf ("% d ", sizeof (int));' расскажет вам, сколько байтов находится в вашей системе. –

+4

Вы должны использовать '% zu' для печати' size_t', а не '% d'. –

+0

@CarlNorum: Полезно знать :) –

ответ

2

Я не думаю, что ваш код ясно показывает, что вы хотите спросить, но ответить на ваш сумму дополнительный вопрос:

% d% х% р, .. они читают постоянный размер (в зависимости от pc) от памяти или зависит от размера соответствующих аргументов?

Они читают размер, зависит от размера конкретного типа на машине. Например, для 32-разрядной машины %d будет читать 4 байта, поскольку предполагается, что переменная равна int.

Я думаю, что этот кусок кода показывает общую идею:

int a = 1089; 
printf("%c\n", a); // prints "A" on a little-endian machine 
printf("%d\n", a); // prints "1089" 
+0

мой код ничего не показывает. Я просто играл с указателями и printf(). в вашем предыдущем коде, я думаю, что второй аргумент printf() просто дает эту функцию, первый байтовый адрес переменной. то первый аргумент printf() показывает, сколько байтов считывается из памяти, начиная с этого адреса. – Michelle

+0

На больших машинах (SPARC, PPC) ваш пример '% c' напечатает нулевой байт, а не' A'. На малогабаритных машинах он будет работать нормально. –

+0

@YuHao не могли бы вы рассказать мне, что будет результатом этого :: printf ("(p1 + 3) =% d", * (p1 + 3)); // nonword-align также в First 1-, когда вы говорите, что код печатает все * p как hex, мне кажется, что printf не знает, сколько байтов составляет * p, он будет смотреть на свой первый аргумент, который % x, поэтому он будет занимать 4 байта (он не смотрит на int32_t для решения 4 байта). – Michelle

2

параметры VARIADIC, так же, как и все другие передачи параметров в C, является передача по значению только. В вашем случае нет адреса чего-либо. В некоторых случаях вы печатаете значение значения указателя. Я попытаюсь объяснить, по порядку:

  1. Первое:

    printf("p1 in hex=%x\n",*p1); 
    

    Печать любой *p1 является как шестнадцатеричное число. Это либо 15, либо 0, в зависимости от того, есть ли у вас машина маленького или большого конца, соответственно.

  2. Следующая:

    printf("(p1+3)=%d",(p1+3)); 
    

    будет пытаться печатать все p1 + 3 как десятичное число. Поскольку p1 - это указатель, это не совсем разумно, и технически это утверждение вызывает неопределенное поведение. Вы должны использовать %p для печати указателя. Предполагая, что указатели и int имеют одинаковый размер на вашем компьютере, вы, вероятно, получите некоторое количество, но, вероятно, не очень значимое.

  3. Последний:

    printf("p1+3=%p",p1+3) 
    

    %p печатает тип указателя, так что эта линия является правильным. Вы, вероятно, получите то же значение, что и в # 2, за исключением шестнадцатеричного формата. Тем не менее, это все зависит от машины/реализации.

Как на другие вопросы:

%x и %d ВСЕГДА сказать Printf использовать формат INT, который в моем компьютере является 4 байта? я прав?

%x для unsigned int и %d для int. В поле %x вы получите шестнадцатеричный вывод и десятичный вывод %d. Если int является четырехбайтовым типом на вашем компьютере, они оба распечатают соответствующие аргументы в 4 байта, которые вы передали.

(p1+3) не является слово выровненного адреса Ox004 +-= 0x007, так что делает Е() показывает в этом случае? По-другому, какие байты которых касается линии 2 Printf?

Поскольку вы сами печатаете значение указателя, выравнивание бессмысленно. Вы не должны использовать %d, чтобы сделать это (как упоминалось выше). Этот адрес, вероятно, не 7, либо ... Я не совсем уверен, откуда вы это взяли.

также %p форматировщик (void *) это потребуется 1 байт для чтения (из полукокса) или так как мы говорим об указателях, и они всегда занимают 4 байта (одно слово)?

%p должно быть в паре с аргументом void *, как вы говорите. Он будет печатать соответствующий размер для типа указателя на вашем компьютере (звучит как 4 байта в вашем случае).

подытожить мои вопросы, %d%x%p, .. делать они читают постоянный размер (в зависимости от ПК) из памяти или это зависит от того, каковы размеры их соответствующих аргументов?

Они не обязательно прочитать ничего из памяти - все зависит от того, как работает ваш ABI и то, что соглашение о вызовах для функций переменных числа вашей машины. Вы должны сопоставлять типы между спецификаторами формата и соответствующими переменными, иначе вы будете вызывать неопределенное поведение.

+0

Не могли бы вы рассказать мне, какой будет выход этого :: printf ("(p1 + 3) =% d", * (p1 + 3)); // non word-align – Michelle

+0

Вы имеете представление о том, что напечатано в случае: printf ("(p1 + 3) =% d", * (p1 + 3)); // non word-align – Michelle

+0

Это зависит от того, является ли ваша машина маленькой, или большой, и как бит 'char'. Либо '0', либо' 21', я думаю. –

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