常量指针对一个恒定值的指针[复制]

时间:2022-12-25 21:42:52

This question already has an answer here:

这个问题已经有了答案:

What is the difference between the following declarations?

以下声明的区别是什么?

char * const a;
const char * a;

In order to understand the difference I wrote this small program:

为了理解我写的这个小程序的区别:

#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;
}

I compiled the program (with gcc 3.4) and ran it. The output highlights the difference rather well:

我编译了这个程序(与gcc 3.4)并运行它。输出结果突出显示了差异:

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


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

However, I had to write the small program to get the answer. In case I'm away from the machine (at an interview for instance), I wouldn't be able to answer the question.

然而,我不得不编写一个小程序来得到答案。如果我离开了机器(比如在面试中),我就不能回答这个问题。

Can someone please explain, by commenting the above example, how the const keyword operates?

有人可以通过上面的例子来解释const关键字是如何操作的吗?

11 个解决方案

#1


152  

char * const a;

means that the pointer is constant and immutable but the pointed data is not.
You could use const_cast(in C++) or c-style cast to cast away the constness in this case as data itself is not constant.

意味着指针是常量和不可变的,但指向的数据不是。您可以使用const_cast(在c++中)或C样式的转换来消除这种情况下的一致性,因为数据本身不是常量。

const char * a;

means that the pointed data cannot be written to using the pointer a. Using a const_cast(C++) or c-style cast to cast away the constness in this case causes Undefined Behavior.

使用const_cast(C++)或C -style cast来抛弃这种情况下的一致性,会导致未定义的行为。

#2


64  

To parse complicated types, you start at the variable, go left, and spiral outwards. If there aren't any arrays or functions to worry about (because these sit to the right of the variable name) this becomes a case of reading from right-to-left.

要解析复杂类型,可以从变量开始,向左旋转,向外旋转。如果没有任何数组或函数需要担心(因为它们位于变量名称的右边),那么这将成为从右到左读取的情况。

So with char *const a; you have a, which is a const pointer (*) to a char. In other words you can change the char which a is pointing at, but you can't make a point at anything different.

对于char *const a;您有一个const指针(*)到char。换句话说,你可以改变a指向的char,但是你不能在任何不同的地方做一个点。

Conversely with const char* b; you have b, which is a pointer (*) to a char which is const. You can make b point at any char you like, but you cannot change the value of that char using *b = ...;.

与const char* b相反;你有b,它是一个指向char的指针(*)。您可以在任何您喜欢的char中生成b点,但是您不能使用*b =…

You can also of course have both flavours of const-ness at one time: const char *const c;.

当然,你也可以同时拥有这两种味道:const char *const c;

#3


59  

char * const a;

*a is writable, but a is not; in other words, you can modify the value pointed to by a, but you cannot modify a itself. a is a constant pointer to char.

*a是可写的,而a不是;换句话说,您可以修改由a指向的值,但是您不能修改它本身。a是一个指向char的常量指针。

const char * a; 

a is writable, but *a is not; in other words, you can modify a (pointing it to a new location), but you cannot modify the value pointed to by a.

a是可写的,而*a不是;换句话说,您可以修改a(指向新的位置),但是不能修改a指向的值。

Note that this is identical to

注意,这是相同的。

char const * a;

In this case, a is a pointer to a const char.

在本例中,a是指向const char的指针。

#4


17  

Now that you know the difference between char * const a and const char * a. Many times we get confused if its a constant pointer or pointer to a constant variable.

现在您已经知道了char * consta和const char * a之间的区别,如果它是一个常量指针或指向常量变量的指针,那么我们就会感到困惑。

How to read it? Follow the below simple step to identify between upper two.

如何阅读?按照下面简单的步骤来确定上两者。

Lets see how to read below declaration

让我们看看如何阅读下面的声明。

char * const a;

read from Right to Left

从右往左读。

Now start with a,

现在开始,

1 . adjacent to a there is const.

1。与a相邻的是const。

char * (const a);

(const char *);

---> So a is a constant (????).

所以a是常数(???)

2 . Now go along you get *

2。现在你去吧。

char (* (const a));

(const char(*));

---> So a is a constant pointer to (????).

--->因此a是一个常量指向(????)

3 . Go along and there is char

3所示。继续,这里是char。

(char (* (const a)));

(char(*(常量)));

---> a is a constant pointer to character variable

---> a是一个指向字符变量的常量指针。

a is constant pointer to character variable. 

Isn't it easy to read?

读起来不容易吗?

Similarily for second declaration

相似的第二次宣言

const char * a;

Now again start with a,

再从a开始,

1 . Adjacent to a there is *

1。与a相邻的是*。

---> So a is a pointer to (????)

--->因此a是指向(???)

2 . Now there is char

2。现在有字符

---> so a is pointer character,

--->因此a是指针字符,

Well that doesn't make any sense!!! So shuffle pointer and character

那没有任何意义!!!所以洗牌和角色。

---> so a is character pointer to (?????)

--->因此a是指向(????)的字符指针。

3 . Now you have constant

3所示。现在你有常数

---> so a is character pointer to constant variable

--->因此a是常量变量的字符指针。

But though you can make out what declaration means, lets make it sound more sensible.

但是,尽管你可以弄清楚什么是宣言,让它听起来更明智些。

a is pointer to constant character variable

#5


13  

The easiest way to understand the difference is to think of the different possibilities. There are two objects to consider, the pointer and the object pointed to (in this case 'a' is the name of the pointer, the object pointed to is unnamed, of type char). The possibilities are:

理解差异的最简单方法是考虑不同的可能性。有两个对象需要考虑,指针和对象指向的对象(在本例中,“a”是指针的名称,对象指向的是未命名的char类型)。可能性是:

  1. nothing is const
  2. 没有什么是常量
  3. the pointer is const
  4. 的指针常量
  5. the object pointed to is const
  6. 物体指向的是常量。
  7. both the pointer and the pointed to object are const.
  8. 指针和指向对象都是常量。

These different possibilities can be expressed in C as follows:

这些不同的可能性可以用C表示:

  1. char * a;
  2. char *;
  3. char * const a;
  4. const char *;
  5. const char * a;
  6. const char *;
  7. const char * const a;
  8. const char * const a;

I hope this illustrates the possible differences

我希望这能说明可能的不同之处。

#6


10  

The first is a constant pointer to a char and the second is a pointer to a constant char. You didn't touch all the cases in your code:

第一个是指向char的常量指针,第二个是指向常量char的指针。你没有触及你代码中的所有案例:

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. */

#7


6  

I will explain it verbally first and then with an example:

我会先口头解释一下,然后再举个例子:

A pointer object can be declared as a const pointer or a pointer to a const object (or both):

指针对象可以被声明为const指针或指向const对象的指针(或两者兼有):

const pointer cannot be reassigned to point to a different object from the one it is initially assigned, but it can be used to modify the object that it points to (called the "pointee").
Reference variables are thus an alternate syntax for constpointers.

一个const指针不能被重新分配来指向它最初分配的对象,但是它可以用来修改它指向的对象(被称为“pointee”)。因此,引用变量是const指针的替代语法。

A pointer to a const object, on the other hand, can be reassigned to point to another object of the same type or of a convertible type, but it cannot be used to modify any object.

另一方面,指向const对象的指针可以被重新分配,指向同一类型或可转换类型的另一个对象,但不能用于修改任何对象。

const pointer to a const object can also be declared and can neither be used to modify the pointee nor be reassigned to point to another object.

也可以声明const对象的const指针,既不能用于修改pointee,也不能被重新分配指向另一个对象。

Example:

例子:

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 
}

Happy to help! Good Luck!

乐意帮助!好运!

#8


5  

Above are great answers. Here is an easy way to remember this:

以上是伟大的答案。这里有一个简单的方法来记住这个:

a is a pointer

是一个指针

*a is the value

*的值

Now if you say "const a" then the pointer is const. (i.e. char * const a;)

如果你说const a,那么指针就是const。(即char * const a;)

If you say "const *a" then the value is const. (i.e. const char * a;)

如果你说“const *a”,那么这个值就是const。(即const char * a;)

#9


2  

You may use cdecl utility or its online versions, like http://www.lemoda.net/c/cdecl/

您可以使用cdecl实用工具或它的在线版本,如http://www.lemoda.net/c/c/cdecl/。

For example:

例如:

void (* x)(int (*[])()); is a declare x as pointer to function (array of pointer to function returning int) returning void

空白(* x)(int(*[])());声明x作为指针指向函数的指针(指向函数返回int的数组)返回void吗?

#10


1  

Trying to answer in simple way:

试图以简单的方式回答:

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)

Constant Pointer:

常量指针:

pointer is constant !!. i.e, the address it is holding can't be changed. It will be stored in read only memory.

指针是常数! !。我。e,它所持有的地址是不能更改的。它将存储在只读存储器中。

Let's try to change the address of pointer to understand more:

让我们试着改变指针的地址来理解更多:

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.

It means once constant pointer points some thing it is forever.

它的意思是一旦常量指针指向某个东西它就会永远存在。

pointer a points only b.

指针只指向b。

However you can change the value of b eg:

但是,你可以改变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);

Pointer to Constant:

指针常量:

Value pointed by the pointer can't be changed.

指针指向的值不能更改。

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!.

#11


0  

const char * a;

This states pointer to constant character. For eg.

这个状态指向常量字符。如。

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

Here a points to a constant char('s',in this case).You can't use a to change that value.But this declaration doesn't mean that value it points to is really a constant,it just means the value is a constant insofar as a is concerned. You can change the value of b directly by changing the value of b,but you can't change the value indirectly via the a pointer.

这里有一个指向常量char('s',在本例中)的点。你不能用a来改变这个值。但是这个声明并不意味着它指向的值是一个常数,它只是意味着它的值是一个常数。你可以通过改变b的值直接改变b的值,但是你不能通过一个指针间接地改变值。

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

* = ' t ';/ /无效b = ' t ';/ /有效

char * const a=&b

This states a constant pointer to char. It constraints a to point only to b however it allows you to alter the value of b.

这是一个指向char的常量指针。它限制a只指向b,但是它允许你改变b的值。

Hope it helps!!! :)

希望它帮助! ! !:)

#1


152  

char * const a;

means that the pointer is constant and immutable but the pointed data is not.
You could use const_cast(in C++) or c-style cast to cast away the constness in this case as data itself is not constant.

意味着指针是常量和不可变的,但指向的数据不是。您可以使用const_cast(在c++中)或C样式的转换来消除这种情况下的一致性,因为数据本身不是常量。

const char * a;

means that the pointed data cannot be written to using the pointer a. Using a const_cast(C++) or c-style cast to cast away the constness in this case causes Undefined Behavior.

使用const_cast(C++)或C -style cast来抛弃这种情况下的一致性,会导致未定义的行为。

#2


64  

To parse complicated types, you start at the variable, go left, and spiral outwards. If there aren't any arrays or functions to worry about (because these sit to the right of the variable name) this becomes a case of reading from right-to-left.

要解析复杂类型,可以从变量开始,向左旋转,向外旋转。如果没有任何数组或函数需要担心(因为它们位于变量名称的右边),那么这将成为从右到左读取的情况。

So with char *const a; you have a, which is a const pointer (*) to a char. In other words you can change the char which a is pointing at, but you can't make a point at anything different.

对于char *const a;您有一个const指针(*)到char。换句话说,你可以改变a指向的char,但是你不能在任何不同的地方做一个点。

Conversely with const char* b; you have b, which is a pointer (*) to a char which is const. You can make b point at any char you like, but you cannot change the value of that char using *b = ...;.

与const char* b相反;你有b,它是一个指向char的指针(*)。您可以在任何您喜欢的char中生成b点,但是您不能使用*b =…

You can also of course have both flavours of const-ness at one time: const char *const c;.

当然,你也可以同时拥有这两种味道:const char *const c;

#3


59  

char * const a;

*a is writable, but a is not; in other words, you can modify the value pointed to by a, but you cannot modify a itself. a is a constant pointer to char.

*a是可写的,而a不是;换句话说,您可以修改由a指向的值,但是您不能修改它本身。a是一个指向char的常量指针。

const char * a; 

a is writable, but *a is not; in other words, you can modify a (pointing it to a new location), but you cannot modify the value pointed to by a.

a是可写的,而*a不是;换句话说,您可以修改a(指向新的位置),但是不能修改a指向的值。

Note that this is identical to

注意,这是相同的。

char const * a;

In this case, a is a pointer to a const char.

在本例中,a是指向const char的指针。

#4


17  

Now that you know the difference between char * const a and const char * a. Many times we get confused if its a constant pointer or pointer to a constant variable.

现在您已经知道了char * consta和const char * a之间的区别,如果它是一个常量指针或指向常量变量的指针,那么我们就会感到困惑。

How to read it? Follow the below simple step to identify between upper two.

如何阅读?按照下面简单的步骤来确定上两者。

Lets see how to read below declaration

让我们看看如何阅读下面的声明。

char * const a;

read from Right to Left

从右往左读。

Now start with a,

现在开始,

1 . adjacent to a there is const.

1。与a相邻的是const。

char * (const a);

(const char *);

---> So a is a constant (????).

所以a是常数(???)

2 . Now go along you get *

2。现在你去吧。

char (* (const a));

(const char(*));

---> So a is a constant pointer to (????).

--->因此a是一个常量指向(????)

3 . Go along and there is char

3所示。继续,这里是char。

(char (* (const a)));

(char(*(常量)));

---> a is a constant pointer to character variable

---> a是一个指向字符变量的常量指针。

a is constant pointer to character variable. 

Isn't it easy to read?

读起来不容易吗?

Similarily for second declaration

相似的第二次宣言

const char * a;

Now again start with a,

再从a开始,

1 . Adjacent to a there is *

1。与a相邻的是*。

---> So a is a pointer to (????)

--->因此a是指向(???)

2 . Now there is char

2。现在有字符

---> so a is pointer character,

--->因此a是指针字符,

Well that doesn't make any sense!!! So shuffle pointer and character

那没有任何意义!!!所以洗牌和角色。

---> so a is character pointer to (?????)

--->因此a是指向(????)的字符指针。

3 . Now you have constant

3所示。现在你有常数

---> so a is character pointer to constant variable

--->因此a是常量变量的字符指针。

But though you can make out what declaration means, lets make it sound more sensible.

但是,尽管你可以弄清楚什么是宣言,让它听起来更明智些。

a is pointer to constant character variable

#5


13  

The easiest way to understand the difference is to think of the different possibilities. There are two objects to consider, the pointer and the object pointed to (in this case 'a' is the name of the pointer, the object pointed to is unnamed, of type char). The possibilities are:

理解差异的最简单方法是考虑不同的可能性。有两个对象需要考虑,指针和对象指向的对象(在本例中,“a”是指针的名称,对象指向的是未命名的char类型)。可能性是:

  1. nothing is const
  2. 没有什么是常量
  3. the pointer is const
  4. 的指针常量
  5. the object pointed to is const
  6. 物体指向的是常量。
  7. both the pointer and the pointed to object are const.
  8. 指针和指向对象都是常量。

These different possibilities can be expressed in C as follows:

这些不同的可能性可以用C表示:

  1. char * a;
  2. char *;
  3. char * const a;
  4. const char *;
  5. const char * a;
  6. const char *;
  7. const char * const a;
  8. const char * const a;

I hope this illustrates the possible differences

我希望这能说明可能的不同之处。

#6


10  

The first is a constant pointer to a char and the second is a pointer to a constant char. You didn't touch all the cases in your code:

第一个是指向char的常量指针,第二个是指向常量char的指针。你没有触及你代码中的所有案例:

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. */

#7


6  

I will explain it verbally first and then with an example:

我会先口头解释一下,然后再举个例子:

A pointer object can be declared as a const pointer or a pointer to a const object (or both):

指针对象可以被声明为const指针或指向const对象的指针(或两者兼有):

const pointer cannot be reassigned to point to a different object from the one it is initially assigned, but it can be used to modify the object that it points to (called the "pointee").
Reference variables are thus an alternate syntax for constpointers.

一个const指针不能被重新分配来指向它最初分配的对象,但是它可以用来修改它指向的对象(被称为“pointee”)。因此,引用变量是const指针的替代语法。

A pointer to a const object, on the other hand, can be reassigned to point to another object of the same type or of a convertible type, but it cannot be used to modify any object.

另一方面,指向const对象的指针可以被重新分配,指向同一类型或可转换类型的另一个对象,但不能用于修改任何对象。

const pointer to a const object can also be declared and can neither be used to modify the pointee nor be reassigned to point to another object.

也可以声明const对象的const指针,既不能用于修改pointee,也不能被重新分配指向另一个对象。

Example:

例子:

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 
}

Happy to help! Good Luck!

乐意帮助!好运!

#8


5  

Above are great answers. Here is an easy way to remember this:

以上是伟大的答案。这里有一个简单的方法来记住这个:

a is a pointer

是一个指针

*a is the value

*的值

Now if you say "const a" then the pointer is const. (i.e. char * const a;)

如果你说const a,那么指针就是const。(即char * const a;)

If you say "const *a" then the value is const. (i.e. const char * a;)

如果你说“const *a”,那么这个值就是const。(即const char * a;)

#9


2  

You may use cdecl utility or its online versions, like http://www.lemoda.net/c/cdecl/

您可以使用cdecl实用工具或它的在线版本,如http://www.lemoda.net/c/c/cdecl/。

For example:

例如:

void (* x)(int (*[])()); is a declare x as pointer to function (array of pointer to function returning int) returning void

空白(* x)(int(*[])());声明x作为指针指向函数的指针(指向函数返回int的数组)返回void吗?

#10


1  

Trying to answer in simple way:

试图以简单的方式回答:

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)

Constant Pointer:

常量指针:

pointer is constant !!. i.e, the address it is holding can't be changed. It will be stored in read only memory.

指针是常数! !。我。e,它所持有的地址是不能更改的。它将存储在只读存储器中。

Let's try to change the address of pointer to understand more:

让我们试着改变指针的地址来理解更多:

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.

It means once constant pointer points some thing it is forever.

它的意思是一旦常量指针指向某个东西它就会永远存在。

pointer a points only b.

指针只指向b。

However you can change the value of b eg:

但是,你可以改变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);

Pointer to Constant:

指针常量:

Value pointed by the pointer can't be changed.

指针指向的值不能更改。

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!.

#11


0  

const char * a;

This states pointer to constant character. For eg.

这个状态指向常量字符。如。

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

Here a points to a constant char('s',in this case).You can't use a to change that value.But this declaration doesn't mean that value it points to is really a constant,it just means the value is a constant insofar as a is concerned. You can change the value of b directly by changing the value of b,but you can't change the value indirectly via the a pointer.

这里有一个指向常量char('s',在本例中)的点。你不能用a来改变这个值。但是这个声明并不意味着它指向的值是一个常数,它只是意味着它的值是一个常数。你可以通过改变b的值直接改变b的值,但是你不能通过一个指针间接地改变值。

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

* = ' t ';/ /无效b = ' t ';/ /有效

char * const a=&b

This states a constant pointer to char. It constraints a to point only to b however it allows you to alter the value of b.

这是一个指向char的常量指针。它限制a只指向b,但是它允许你改变b的值。

Hope it helps!!! :)

希望它帮助! ! !:)