常量指针与常量值上的指针

以下声明有什么区别?

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关键字是如何运作的吗?

 char * const a; 

意味着指针是不变且不变的,但指向的数据不是。
在这种情况下,你可以使用const_cast (使用C ++)或c-style强制转换const,因为数据本身不是常量。

 const char * a; 

意味着使用指针a不能写入指向的数据。 在这种情况下,使用const_cast (C ++)或c风格的强制types转换常量会导致“ 未定义的行为”

 char * const a; 

*a是可写的,但a不是; 换句话说,你可以修改a 指向的值,但是你不能修改a自己。 a是一个指向char常量指针

 const char * a; 

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

请注意,这是相同的

 char const * a; 

在这种情况下, a是一个指向const char指针

为了parsing复杂的types,你从variables开始,向左,向外旋转。 如果没有任何数组或函数需要担心(因为它们位于variables名称的右侧),则会成为从右向左读取的情况。

所以用char *const a; 你有a ,这是一个const指针( * )到一个char 。 换句话说,你可以改变指向的字符,但你不能指出任何不同的地方。

const char* b;相反const char* b; 你有b ,这是一个指针( * )为constchar 。 你可以用任何你喜欢的字符来创buildb点,但是你不能用*b = ...;来改变这个字符的值*b = ...;

你当然也可以同时拥有const的所有风格: const char *const c;

现在你知道了char * const aconst char * a之间的区别。 很多时候,如果一个常量指针或者一个指向常量variables的指针,我们会感到困惑。

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

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

 char * const a; 

从右到左阅读

现在从a开始,

1。 相邻有a const

char * (const a) ;

—>所以a是一个constant (????)

2。 现在去一起你得到*

char (* (const a)) ;

—>所以a是一个constant pointer (????)

3。 去吧,有char

(char (* (const a))) ;

—> a是一个charactervariables的constant pointer

 a is constant pointer to character variable. 

阅读起来不容易吗?

第二个声明类似

 const char * a; 

现在再次从a开始,

1。 相邻a*

—>所以a是一个pointer (????)

2。 现在有char

—>所以apointer character

那么这没有任何意义! 所以洗牌和character

—>所以acharacter pointer (?????)

3。 现在你已经constant

—>所以aconstantvariables的character pointer

但是,尽pipe你可以弄清楚声明是什么意思,但让它听起来更合理。

 a is pointer to constant character variable 

理解差异的最简单方法就是考虑不同的可能性。 有两个对象需要考虑,指针和指向的对象(在这种情况下,“a”是指针的名称,指向的对象是未命名的,types为char)。 可能性是:

  1. 没有什么是常量
  2. 指针是const
  3. 指向的对象是const
  4. 指针和指向对象都是const的。

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

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

我希望这说明可能的差异

第一个是一个指向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. */ 

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

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

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

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

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 } 

乐于帮助! 祝你好运!

以上是很好的答案。 这是一个简单的方法来记住这一点:

一个是指针

* a是价值

现在,如果你说“const a”,那么指针是const。 (即char * const a;)

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

您可以使用cdecl实用程序或其在线版本,如http://www.lemoda.net/c/cdecl/

例如:

void (* x)(int (*[])()); 是一个declare x as pointer to function (array of pointer to function returning int) returning void

试图以简单的方式回答:

 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. 

这意味着一旦不变的指针指向一些永远的东西。

指针只有ab

但是你可以改变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!. 
 const char * a; 

这表示指向常量字符的指针。 例如。

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

这里指向一个常量字符(在本例中为's')。你不能用a来改变这个值。但是这个声明并不意味着它指向的值实际上是一个常量 ,它只是意味着这个值就a而言是一个常数。 您可以通过更改b的值直接更改b的值,但是不能通过指针间接更改值。

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

 char * const a=&b 

这表示一个常量指向char的指针。 它约束a只指向b但它允许你改变b的值。

希望它有帮助! 🙂