Вопрос по c – указатель константы против указателя на постоянное значение [дубликат]

138

This question already has an answer here:

В чем разница между следующими декларациями?

char * const a;
const char * a;

Чтобы понять разницу, я написал эту небольшую программу:

#include <stdio.h>
#include <stdlib.h>


int main (int argc, char **argv)
{
    char a = 'x';
    char b = 'y';

    char * const pc1 = &a;
    const char * pc2 = &a;

    printf ("Before\n");
    printf ("pc1=%p\n", pc1);
    printf ("*pc1=%c\n", *pc1);
    printf ("pc2=%p\n", pc2);
    printf ("*pc2=%c\n", *pc2);

    *pc1 = b;
/*     pc1 = &b; */

/*     *pc2 = b; */
    pc2 = &b;

    printf ("\n\n");

    printf ("After\n");
    printf ("pc1=%p\n", pc1);
    printf ("*pc1=%c\n", *pc1);
    printf ("pc2=%p\n", pc2);
    printf ("*pc2=%c\n", *pc2);

    return EXIT_SUCCESS;
}

Я скомпилировал программу (с gcc 3.4) и запустил ее. Выходные данные довольно хорошо подчеркивают разницу:

Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x


After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x

Однако мне пришлось написать небольшую программу, чтобы получить ответ. Если я нахожусь вдали от машины (например, на собеседовании), я не смогу ответить на этот вопрос.

Может кто-нибудь объяснить, комментируя приведенный выше пример, какconst ключевое слово действует?

Я считаю, что заголовок должен читаться как - "константный указатель против указателяto постоянное значение & quot; RBT
Более полные ответы приведены ниже, но мне нравится думать, чтоconst «связывается со следующим токеном». Так вchar * const a этоaсама переменная, которая не может быть изменена. Вconst char * a это указатель на символ, который нельзя изменить. davmac

Ваш Ответ

11   ответов
12

Первый - это постоянный указатель на символ, а второй - указатель на постоянный символ. Вы не коснулись всех случаев в своем коде:

char * const pc1 = &a; /* You can't make pc1 point to anything else */
const char * pc2 = &a; /* You can't dereference pc2 to write. */

*pc1 = 'c' /* Legal. */
*pc2 = 'c' /* Illegal. */

pc1 = &b; /* Illegal, pc1 is a constant pointer. */
pc2 = &b; /* Legal, pc2 itself is not constant. */
Error: User Rate Limit Exceeded rahmu
169

char * const a;

что указатель является постоянным и неизменным, а указанные данные - нет.
Вы могли бы использоватьconst_cast(в C ++) или приведение в стиле c для исключения константности в этом случае, поскольку сами данные не являются постоянными.

const char * a;

, что указанные данные не могут быть записаны с использованием указателя a. Используяconst_cast(C ++) или c-style приведение, чтобы отбросить константу в этом случае вызываетUndefined Behavior.

const char * aError: User Rate Limit ExceedednotError: User Rate Limit ExceededaError: User Rate Limit Exceededgist.github.com/andyli/b4107c8910208fe54764
Error: User Rate Limit ExceededsometimesError: User Rate Limit Exceeded
5

Выше отличные ответы. Вот простой способ запомнить это:

а это указатель

* а это значение

Теперь, если вы скажете "const a" тогда указатель постоянный. (то есть char * const a;)

Если вы говорите «const * a» тогда значение является постоянным. (то есть const char * a;)

59

char * const a;

*a доступно для записи, ноa не является; другими словами, вы можете изменить значениеpointed to отa, но вы не можете изменитьa сам.a этоconstant pointer to char.

const char * a; 

a доступно для записи, но*a не является; другими словами, вы можете изменитьa (указывая на новое место), но вы не можете изменить значениеpointed to отa.

Обратите внимание, что это идентично

char const * a;

В этом случае,a этоpointer to a const char.

83

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

Так сchar *const a; у тебя естьa, который являетсяconst указатель (*) кchar, Другими словами, вы можете изменить символ, которыйa указывает на, но вы не можете сделатьa указать на что-то другое.

Наоборот сconst char* b; у тебя естьb, который является указателем (*) кchar которыйconst, Ты можешь сделатьb укажите на любой символ, который вам нравится, но вы не можете изменить значение этого символа, используя*b = ...;.

Вы также можете, конечно, иметь оба вкуса константности одновременно:const char *const c;.

Error: User Rate Limit Exceededcdecl.orgError: User Rate Limit Exceeded
14

Самый простой способ понять разницу - подумать о разных возможностях. Необходимо рассмотреть два объекта, указатель и объект, на который указывают (в данном случае «a» - это имя указателя, на который указывает объект, без имени, типа char). Возможности:

  1. nothing is const
  2. the pointer is const
  3. the object pointed to is const
  4. both the pointer and the pointed to object are const.

Эти различные возможности могут быть выражены в C следующим образом:

  1. char * a;
  2. char * const a;
  3. const char * a;
  4. const char * const a;

Я надеюсь, что это иллюстрирует возможные различия

5

Сначала я объясню это устно, а затем на примере:

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

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

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

& # XA0;const pointer to a const object также может быть объявлен и не может быть использован для изменения объекта или переназначен для указания на другой объект.

Пример:

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 
}

Рад был помочь! Удачи!

2

Вы можете использовать утилиту cdecl или ее онлайн-версии, напримерhttps://cdecl.org/

Например:

void (* x)(int (*[])()); это declare x as pointer to function (array of pointer to function returning int) returning void

0

const char * a;

Указывает указатель на постоянный символ. Например,

char b='s';
const char *a = &b;

Вотa   указывает на постоянный символ (в данном случае "s"). Вы не можете использоватьa изменить это значение. Но это объявление не означает, что значение, на которое оно указывает,really a constant, это просто означает, что значение является постоянным, посколькуa обеспокоен. Вы можете изменить значениеb непосредственно путем изменения значенияb, но вы не можете изменить значение косвенно черезa указатель.

*a='t'; //INVALID b='t' ; //VALID

char * const a=&b

Это константный указатель на символ. Это ограниченияa указывать только наb Однако это позволяет изменить значениеb.

Надеюсь, поможет!!! :)

1

Попытка ответить простым способом:

char * const a;  => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer )
const char * a;  => a is (*) pointer to char constant             {L <- R}. =>( Pointer to Constant)

Постоянный указатель:

Указатель постоянен! т.е. адрес, который он содержит, не может быть изменен. Он будет храниться в постоянной памяти.

Попробуем изменить адрес указателя, чтобы понять больше:

char * const a = &b; 
char c;
a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable.

Это означает, что когда постоянный указатель указывает на что-то, это навсегда.

указательa только очкиb.

Однако вы можете изменить значениеb например:

char b='a';
char * const a =&b;

printf("\n print a  : [%c]\n",*a);
*a = 'c';
printf("\n now print a  : [%c]\n",*a);

Указатель на константу:

Значение, на которое указывает указатель, не может быть изменено.

const char *a;
char b = 'b';
const char * a =&b;
char c;
a=&c; //legal

*a = 'c'; // illegal , *a is pointer to constant can't change!.
22

Теперь, когда вы знаете разницу междуchar * const a а такжеconst char * a, Много раз мы путаемся, если это постоянный указатель или указатель на постоянную переменную.

Как это читать? Выполните следующий простой шаг, чтобы определить между двумя верхними.

Давайте посмотрим, как читать ниже декларации

char * const a;

читать справа налево

Теперь начнем сa,

1 рядом сa естьconst.

символ *(const a);

--- & GT; Такa этоconstant (????).

2 А теперь иди ты получишь*

голец(* (const a));

--- & GT; Такa этоconstant pointer в(????).

3 Идите и естьchar

(char (* (const a)));

--- & GT;a этоconstant pointer вcharacter переменная

a is constant pointer to character variable. 

Разве это не легко читать?

Аналогично для второго объявления

const char * a;

Теперь снова начнем сa,

1 Рядом сa есть*

--- & GT; Такa этоpointer к (????)

2 Сейчас естьchar

--- & GT; такa являетсяpointer character,

Ну, это не имеет никакого смысла !!! Так перемешатьpointer а такжеcharacter

--- & GT; такa являетсяcharacter pointer в(?????)

3 Теперь у вас естьconstant

--- & GT; такa являетсяcharacter pointer вconstant переменная

Но хотя вы можете разобрать, что означает объявление, давайте сделаем его более осмысленным.

a is pointer to constant character variable
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded rahmu
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы