2016-02-18 5 views
1

ЖАЛЬ, я неправильно понял мои результаты, * р и р отличаютсяC, массив указателей: int n [5], int * p [5], назначить p [i] = & n [i], почему * p совпадает с p?


Я пытаюсь сделать представление о массиве указателей.

Я написал

int n[5] = {1,2,3,4,5}; 
int *p[5]; 
for(i = 0; i < 5; i++){ 
    p[i] = &n[i]; 
} 

до сих пор так хорошо.

, и я понимаю, что

printf("%0x\n", *p); 

дает мне адрес первого указателя в массиве.


, что меня беспокоит это р, только р, ни звездочки, ни скобки.

потому

printf("%0x\n", *p); 
printf("%0x\n", p); 

[дайте мне то же самое. Почему p также адрес первого указателя в массиве?] НЕПРАВИЛЬНО, ИЗБЕГАЙТЕ!

Что именно означает p, когда объявлен массив указателей, указанных выше?


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

int main(int argc, char *argv[]){ 
    for(int i = 0; i < argc; i++){ 
     printf("%s\n",argv[i]); //why not *argv[i]?? 
    } 
} 

так argv объявлен как массив указателей, не должны давать argv[i] адрес вместо строки, где он указывает? потому что перед ним нет звездочки.

Заранее спасибо.

+0

Я не могу воспроизвести проблему. '* p' и' p' в моем случае разные. –

+0

DAMN, вы правы, я ошибся! есть небольшая разница, и я пропустил это! – NubeToAdroit

ответ

1

При использовании только p он распадается на указатель на первый элемент в массиве p, т.е. p эквивалентно &p[0].

Когда вы разыгрываете этот указатель, вы получаете указатель, хранящийся в p[0]. То есть когда вы делаете *p, это то же самое, что и делать *&p[0], а разыменованные и адресные операторы вытаскивают друг друга, давая вам только p[0], что в вашем случае равно &n[0].

Также обратите внимание, что если вы хотите напечатать указатели, используя printf, вы должны использовать формат "%p" (и действительно передавать void * в качестве аргумента).


на самом деле не связаны вопрос, потому что argv представляет собой массив указателей на символы. Для любого действительного индекса i выражение argv[i] дает вам указатель типа char *.Если вы разыщите этот указатель, вы получите символ, на который указывает argv[i], т. Е. Один символ.

+0

Это было очень полезно !! ТКС !! – NubeToAdroit

4

p, just p, no asterisk, without brackets дает адрес первого элемента массива p[]. *p с другой стороны дает значение первого элемента массива p[], который является адресом первого элемента массива n[], в соответствии с кодом, который вы показываете.


Давайте рассмотрим пример, предполагая, что целое имеет размер 4 байта и адрес, если размером 8 байт, а первая программа, которую вы показали.

int n[5] = {1,2,3,4,5}; 
int *p[5]; 
for(i = 0; i < 5; i++) 
{ 
    p[i] = &n[i]; 
} 

Массивы будут выглядеть примерно так. (Адреса принимаются для объяснения цели, они не являются реальными).

n[] = { 1, 2, 3, 4, 5}; //these are integers 
    //^^^^^
    // 100 104 108 112 116 these are the addresses of the elements of array n[] 

p[] = { 100, 104, 108, 112, 116}; // these are pointer to integers 
    //^^^^^
    // 200 208 216 224 232 these are adddress of the elements of array p[] 

Теперь, р, только р, не звездочки, никакие кронштейнов не дали бы значение 200, который является адресом первого элемента массива p[].

Как мудрый n дал бы значение 100.

*p даст значение 100, которое является элементом, хранящимся в первой позиции массива p[].

+0

, которые очень помогли, огромное спасибо! – NubeToAdroit

+0

@NubeToAdroit, Добро пожаловать. :) – Haris

1

Учитывая,

int n[5] = {1,2,3,4,5}; 
int *p[5]; 
for(int i = 0; i < 5; i++){ 
    p[i] = &n[i]; 
} 

printf("0x%p\n", *p); 
printf("0x%p\n", p); 

Выход определенно не ожидается, будет то же самое.

я

0x0x7fffe0c40b40 
0x0x7fffe0c40b60 

на моем рабочем столе.

Если я использую:

printf("%0x\n", *p); 
printf("%0x\n", p); 

Я получаю следующее предупреждение при компиляции с использованием gcc -Wall

soc.c: In function ‘test’: 
soc.c:12:4: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=] 
    printf("%0x\n", *p); 
    ^
soc.c:13:4: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int **’ [-Wformat=] 
    printf("%0x\n", p); 

Даже тогда, я получаю следующий результат:

3ef18920 
3ef18940 

Как вы можете видите, они не то же самое.

Возможно, вы видите симптомы неопределенного поведения из-за использования неправильного спецификатора формата.

Просмотреть результаты обеих форм по адресу http://ideone.com/73UoDa.

+0

действительно, я неправильно прочитал свои результаты, спасибо за вашу помощь! – NubeToAdroit

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