Подтвердить что ты не робот

Как ответить на этот тест интервью о постоянных указателях?

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

#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 байта,
и q также увеличит 4 байта;

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

c) ошибка появится в программе

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

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

Ответ 1

int* const p=NULL;

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

Таким образом:

p++;

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

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

(*p)++;

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


int const *q=NULL;

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

Таким образом:

q++;

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

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

(*q)++;

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

Ответ 2

Как будет выглядеть выше программа?

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

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

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


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

Ответ 3

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

Они специально говорят там:

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

char c; char * const cp = & c;

Это просто. cp - указатель на a char, что и есть быть, если const не было. const означает, что cp не должно быть изменен, хотя что бы это ни указывало может быть: указатель постоянный, а не на что он указывает. Другой раунд

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

Ответ 4

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

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

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

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

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 
}

Ответ 5

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

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

  bool IsCorrupt (Ptr<Packet> pkt);

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