Как ответить на этот собеседование о постоянных указателях? - PullRequest
16 голосов
/ 20 июня 2011

У меня было интервью, в котором мне задавали этот вопрос

#include<stdio.h>
int main ()
{
int* const p=NULL;
int const *q=NULL;
p++;
q++;
printf("%d\n",p);
printf("%d\n",q);
}

Как будет вести себя вышеуказанная программа

a) p увеличит на 4 байта;инкремент 4 байта;

b) p будет равно нулю
q будет указывать на память на 4 байта вперед;

в) ошибка появится в вышеуказанной программе

Я не могу понять, в чем разница между утверждениями

int* const p=NULL;
int const *q=NULL;

Ответы [ 5 ]

28 голосов
/ 20 июня 2011

int* const p=NULL;

p - это константный указатель на целое число. Указатель является константой (значение указателя нельзя изменить); целое число, на которое указывают, не является постоянным (целочисленное значение может быть изменено).

Итак, заявление:

p++;

не удастся скомпилировать из-за попытки изменить постоянное значение (указатель).

и утверждение:

(*p)++;

будет увеличивать целочисленное значение, на которое указывает указатель p (но поскольку NULL назначено *1021*, это будет неопределенное поведение )


int const *q=NULL;

q - указатель на константа-целое число . Указатель не является константой (значение указателя можно изменить); целое число указывает на константу IS (целое значение не может быть изменено).

Итак, заявление:

q++;

изменит указатель q, чтобы он указывал на память на 4 байта вперед (при условии, что sizeof(int) равен 4). (поскольку q назначено NULL, q будет 0x4 - Я предполагаю, что NULL равен нулю (что верно для всех текущих реализаций), увеличивающийся указатель NULL на самом деле неопределенное поведение )

и утверждение:

(*q)++;

не удастся скомпилировать, потому что попытка изменить постоянное значение (целое число, на которое указывает константа)

25 голосов
/ 20 июня 2011

Как будет вести себя вышеуказанная программа?

Ответ довольно прост: программа не будет компилироваться.

Постфикс ++ требует изменяемого lvalue в качестве аргумента;p нельзя изменить, поскольку он const -качественен.

const после * означает, что указатель квалифицирован;если const появляется перед *, как в объявлении q, это означает, что объект, на который указывает указатель, квалифицирован.Вы можете декодировать синтаксис объявления C, используя правило по часовой стрелке / спираль .


Если вы удалите p и все ссылки на него из программы, чтобы только строки, содержащие q остаются, ответ в том, что программа демонстрирует неопределенное поведение: вы не можете выполнять арифметику с нулевым указателем (по крайней мере, если результат не является нулевым указателем).

2 голосов
/ 20 июня 2011

http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

Там специально сказано:

Интересная дополнительная функция появляется сейчас.Что это значит?

char c;char * const cp = & c;

Это действительно просто;cp - это указатель на символ, который будет именно таким, каким он был бы, если бы const не было.Const означает, что cp не должен быть изменен, хотя на что бы он ни указывал - указатель постоянен, а не то, на что он указывает.Обратный ход -

const char * cp;Это означает, что теперь cp - это обычный, изменяемый указатель, но то, на что он указывает, не должно быть изменено.Таким образом, в зависимости от того, что вы выбираете, указатель и то, на что он указывает, могут быть модифицируемыми или нет;просто выберите соответствующую декларацию.

1 голос
/ 03 августа 2015

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

Объект указателя может быть объявлен как указатель const или указатель на объект const (или оба):

A константный указатель нельзя переназначить, чтобы он указывал на объект, отличный от того, которому он был изначально назначен, но его можно использовать для изменения объекта, на который он указывает (называемого "указателем").Таким образом, ссылочные переменные являются альтернативным синтаксисом для указателей констант.

Указатель на константный объект , с другой стороны, может быть переназначен для указания на другой объект того же типа или конвертируемоготипа, но его нельзя использовать для изменения какого-либо объекта.

A const-указатель на const-объект также может быть объявлен и не может быть использован для изменения указателя или переназначения для указания надругой объект.

Пример:

void Foo( int * ptr,
         int const * ptrToConst,
         int * const constPtr,
         int const * const constPtrToConst ) 
{ 
    *ptr = 0; // OK: modifies the "pointee" data 
    ptr = 0; // OK: modifies the pointer 

    *ptrToConst = 0; // Error! Cannot modify the "pointee" data
     ptrToConst = 0; // OK: modifies the pointer 

    *constPtr = 0; // OK: modifies the "pointee" data 
    constPtr = 0; // Error! Cannot modify the pointer 

    *constPtrToConst = 0; // Error! Cannot modify the "pointee" data 
    constPtrToConst = 0; // Error! Cannot modify the pointer 
}
0 голосов
/ 05 июня 2014

Я только что добавил предоставленный код и запустил его, enter image description here
Затем я скомпилировал его, и ошибка указателя, доступного только для чтения, не может быть изменена, и в нашем случае увеличивается, как показано ниже. Прервать компиляцию enter image description here Я только хочу привести пример, где мы не можем использовать указатели const .

Еще один пример из сетевого симулятора ns3, который разъясняет постоянное использование указателя. когда мы определим модель ошибки, которая будет проверять поступающие пакеты. функция на После того как IsCorrupt вернет true (в случае ошибки), программа может затем отбросить или удалить пакет из своего буфера данных.

  bool IsCorrupt (Ptr<Packet> pkt);

Обратите внимание, что мы не передаем указатель const, что позволяет функции изменять пакет, если IsCorrupt () возвращает true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...