常量指针与常量值上的指针
以下声明有什么区别?
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
,这是一个指针( *
)为const
的char
。 你可以用任何你喜欢的字符来创buildb
点,但是你不能用*b = ...;
来改变这个字符的值*b = ...;
。
你当然也可以同时拥有const的所有风格: const char *const c;
。
现在你知道了char * const a
和const 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
是一个character
variables的constant
pointer
a is constant pointer to character variable.
阅读起来不容易吗?
第二个声明类似
const char * a;
现在再次从a
开始,
1。 相邻a
有*
—>所以a
是一个pointer
(????)
2。 现在有char
—>所以a
是pointer
character
,
那么这没有任何意义! 所以洗牌和character
—>所以a
是character
pointer
(?????)
3。 现在你已经constant
—>所以a
是constant
variables的character
pointer
但是,尽pipe你可以弄清楚声明是什么意思,但让它听起来更合理。
a is pointer to constant character variable
理解差异的最简单方法就是考虑不同的可能性。 有两个对象需要考虑,指针和指向的对象(在这种情况下,“a”是指针的名称,指向的对象是未命名的,types为char)。 可能性是:
- 没有什么是常量
- 指针是const
- 指向的对象是const
- 指针和指向对象都是const的。
这些不同的可能性可以用C表示如下:
- char * a;
- char * const a;
- const char * a;
- 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.
这意味着一旦不变的指针指向一些永远的东西。
指针只有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!.
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
的值。
希望它有帮助! 🙂