2015-01-21 4 views
0

В следующем коде p является указателем на int. Совершенно ясно, что p указывает на адрес i. Через мое исследование я знаю & p указывает на адрес указателя p. Но я не понимаю, зачем вам нужен отдельный адрес для этого. А также, когда вы будете использовать & p.Если p является указателем на int, где можно использовать & p

int main() { 
    int i = 3, *p = &i; 
    printf("%p",&p); 
    printf("%p",p); 
    return 0; 
} 
+4

'зачем вам нужен отдельный адрес?' - переменная 'p' находится в памяти, поэтому у нее есть адрес (по определению« что-то, что находится в памяти »). –

ответ

3

Если p является указателем на int затем

int **q = &p; 

Если вы хотите использовать указатель на указатель, а затем использовать адрес одного указателя, чтобы назначить его на указатель на указатель.

Просто чтобы указать, что указатель также является типом данных и хранится в ячейке памяти, и в нем хранится допустимая ячейка памяти. Адрес, в котором хранится эта действительная ячейка памяти, задается &p

Также необходимо исправить ваш printf(). %p ожидает void *

printf("%p",(void *)p); 
+0

no printf не является типичным, вы можете ввести любой указатель. – CashCow

+1

@CashCow В этой ссылке есть много хороших ответов, в которых говорится, что это хорошо (void *) при печати указателей http://stackoverflow.com/questions/9053658/correct-format-specifier-to-print-pointer-address Стандарт говорит ' p Аргумент указателя void * печатается в шестнадцатеричном виде (как будто на% # x или% # lx). он должен быть указателем на void.' – Gopi

+1

Не используйте в этом случае термин «двойной указатель». Это не означает * указатель на указатель *. Это означает «двойной» указатель ». – haccks

2

Тривиального примера:

int nochange(int *c, int *val) 
{ 
    c = val; // Changes local pointer c to point to val 
      // Note that C passes copies of the arguments, not actual references. 
} 
int do_change(int **c, int *val) 
{ 
    *c = val; // Accesses the real pointer c at its real location and makes 
       // that one point to val 
       // Even though c is a pointer-to-pointer copy, its value is 
       // copied too, and the value is the address of the real c 
} 

int main() 
{ 
    int a = 1; 
    int b = 2; 
    int *c = &a; // A pointer is also a datatype that resides in memory 

    printf("%d\n", *c); // Will print 1 
    nochange(c, &b); 
    printf("%d\n", *c); // Will print 1 
    do_change(&c, &b); 
    printf("%d\n", *c); // Will print 2 because c now points to b 
} 

У меня есть подобный ответ с немного более подробно здесь о указателе против указателя на указатель: pointer of a pointer in linked list append

+0

Почему downvote? Объясните. – Jite

+0

Я думаю, что кто-то занижен, потому что это не вопрос, я думаю, что ОП это знает. –

+0

', а также когда вы будете использовать & p', я прочитаю это как общий вопрос указателей. Мой ответ дает прекрасный пример того, когда его использовать. – Jite

2

Но я не спрашивайте, зачем вам нужен отдельный адрес для этого

Вы не делаете, но существует адрес оператора, так что вы можете взять адрес указателя, который является то, что

printf("%p\n", &p); 

печати.

А также, когда вы используете &p

Есть случаи, когда это может быть полезно, рассмотрим, например, что вам нужно передать указатель на функцию, которая может быть переназначен в функцию, вы может сделать что-то вроде этого

int allocateIntegerArray(int **pointerToPointer, size_t someSize) 
{ 
    if (pointerToPointer == NULL) 
     return 0; 
    *pointerToPointer = malloc(someSize * sizeof(int)); 

    return (*pointerToPointer != NULL); 
} 

, то вы могли бы использовать этот Funciton следующим образом

int *pointer; 

if (allocateIntergerArray(&pointer, 10) == 0) 
{ 
    fprintf(stderr, "Error, cannot allocate integer array\n"); 
    /* do some extra cleanup or recover from this error, or exit() */ 
    exit(0); 
} 

Сами указатели также являются переменными, и поэтому они должны быть сочтены где-то, поэтому адрес указателя указывает вам, где хранится указатель, это значение указывает вам, на что оно указывает.

Зная, где оно хранится, вы можете делать такие вещи, как описано выше.