2015-10-03 2 views
-4

Я имел в виду NULL Pointer в What's the difference between a null pointer and a void pointer? Согласно сообщению ответа от @AnT, «Формально каждый тип указателя (int *, char * и т. Д.) Имеет свой собственный выделенный нулевой указатель значение "Условное значение для указателя NULL

Я написал простую программу. Но значение указателя не фиксируется для целого или символа. Иногда это меняется. Итак, как мы можем заключить, что указатель NULL для int имеет фиксированное значение? Кроме того, значение указателя никогда 0.

#include <stdio.h> 

int main() 
{ 
    int a; 
    char *ptr; // Declaring a pointer without initializing it 
    int *ptrToInt; 

    if(ptr) 
    { 
     printf("Pointer is not NULL\n"); 
     printf("Value of pointer = %x\n",ptr); 
     printf("Value of pointer = %x\n",ptrToInt); 
    } 
    else 
    { 
     printf("Pointer is NULL\n"); 
     printf("Value of pointer = %x",ptr); 
     printf("Value of pointer = %x\n",ptrToInt); 
    } 
    return 0; 
} 
+3

Ваш 'if (ptr)' является неопределенным поведением, так как 'ptr' является неинициализированной автоматической переменной. См. Проект стандарта C11 «6.2.4 Длительность хранения объектов, раздел 6» и «Приложение J.2 Неопределенное поведение». – EOF

+0

Я не вижу нулевого указателя, но только два неинициализированных указателя. – alk

+0

должен быть 'char * ptr = NULL;' – nafsaka

ответ

1

NULL является значение, которое означает, что указатель любого типа не является действительным, и void* типа. В C или C++ константу 0 можно назначить указателю любого типа и установить для нее нулевой указатель этого типа. Константа NULL может быть объявлена ​​как 0, ((void*)0) или что-то еще в необычной системе.

A NULL Указатель - это указатель любого типа, установленный на недопустимое значение NULL. Вы должны сами установить это значение; просто оставляя указатель без инициализатора, он может содержать мусор. (Технически существует несколько исключений, но всегда инициализируются ваши переменные.)

A void* - тип, который может хранить любой указатель другого типа (кроме указателя на функцию). Он не может быть разыменован, и вы не можете индексировать его как массив или делать арифметику указателя на нем. Он обычно используется в качестве синтаксического сахара, чтобы вы могли вызвать функцию, такую ​​как memset(), которая просто обрабатывает адрес, который вы передаете ему, в виде массива байтов, который нужно заполнить, или назначить p = malloc(…) без явного приведения. Другими словами, когда вы просто относитесь к указателю как к нетипизированному блоку памяти, который позже будет превращен в какой-то объект, но вам все равно.

Если вы хотите протестировать значения битов нулевых указателей разных типов, я предлагаю отливку до uintptr_t и спецификатор формата в <inttypes.h>. В большинстве, но не во всех реализациях, все они будут равны нулю.

+0

К сожалению, стандарт C не требует константы нулевого указателя иметь тип 'void *'. Нет указателя '' NULL', но _null pointer_. 'NULL' - это просто макрос. Фактическое использование значения для константы _null pointer_ не определяется стандартом. Он просто должен сравнивать unequel с любым действительным значением указателя. – Olaf

+0

И вы ** всегда ** должны инициализировать переменную 'auto'; исключений нет. Единственная разница - это _how_ to. Вы не используете _initializer_, но можете использовать назначение. 'void *' не является "синтаксическим сахаром", а обязательным типом, поскольку он является единственным, который может быть преобразован в/из любого другого _объекта pointer_. – Olaf

+0

Добавление C++ - очень плохая идея, поскольку C++ 11 представил истинный 'nullptr', который явно отличается от пропущенного целого числа' 0', как это было сделано ранее на обоих языках. Использование '0' в C++ farianlly было устаревшим (поэтому они, наконец, узнали от более старых языков, таких как Pascal). Надеюсь, C последует, но я не оптимист. – Olaf