补充知识
- “const int i”与“int const i”之间的区别
- 对变量来说,const 关键字可以限定一个变量的值不允许改变,从而保护被修饰的东西,防止意外修改,在一定程度上可以提高程序的安全性和可靠性。
代码
const int *
int i1 = 10;
int i2 = 20;
const int *p = &i1;
/* 输出结果是10 */
printf("%d\n", *p);
p = &i2;
/* 输出结果是20 */
printf("%d\n", *p);
i2 = 30;
/* 输出结果是30 */
printf("%d\n", *p);
- 为什么 p 的值是可以被修改的,它可以重新指向另一个地址呢
- 这里的 const 关键字修饰的是整个“*p”,而不是 p。所以这里的“*p”是不能被赋值的,也就是说我们不能通过“*p”来修改 i2 的值。
- 其次,p 前并没有用 const 关键字进行修饰,所以 p 是指针变量,能被赋值重新指向另一内存地址。也就是说下面的代码是合法的:p = &i2; i2 = 30;
- “int*const p”这种声明形式。很显然,这里的 const 是写在 p 前和 * 号后的,而不是写在“*p”前的,所以它是用来修饰限定 p 的
int *const
int i1 = 10;
int i2 = 20;
int *const p = &i1;
/* 输出结果是10 */
printf("%d\n", *p);
/* p=&i2; p不能再这样重新赋值了,即不能再指向另一个新地址*/
/* 可以通过*p修改i1的值*/
i1 = 30;
/* 输出结果是30 */
printf("%d\n", *p);
- p 因为有了 const 的修饰,所以只是一个指针常量。因此,这里的 p 值是不能重新赋值修改的,它只能永远指向初始化时的内存地址。即下面的代码是不合法的:
- p = &i2; //p不能再这样重新赋值了,即不能再指向另一个新地址
- 但是,也正因为这里的整个“*p”的前面没有 const 修饰。也就是说,“*p”是变量而不是常量,所以我们可以通过“*p”来修改它所指内存 i1 的值。因此,下面的语句是合法的:
- 由此可见,如果关键字 const 直接写在“*p”前,则程序不能修改“*p”,但可以修改 p;如果关键字 const 直接写在 p 前,则程序不能修改的是 p,但可以通过“*p”来修改它所指内存的值。理解这两点很重要,否则很难掌握“const int*p”与“int*const p”两者之间的根本区别。
总结
const int i=10;
int *p;
/* 强制类型转换*/
p= (int *) &i;
printf("*p=%d\n",*p)
/*这种赋值是合法的*/
*p=20;
printf("i=%d\n",i);
printf("*P=%d\n",*p);
- 因为 const int 类型的 i 的地址是不能赋值给指向 int 类型地址的指针 p 的(否则 p 岂不是能修改i的值)。因此下面的语句是不合法的:p = &i
- 可以通过强制类型转换进行赋值,因此下面的这种赋值方法是合法的 p= (int *) &i; *p=20;
- 尽管可以通过强制类型转换进行赋值,也不能通过“*p=20”来修改 i 的值。因此,“printf("i=%d\n”,i)”输出的结果是 10,并不是 20。
- 示例运行结果为:*p=10 i=10 *p=20
第一个是指针,第二个是指针所指物
p是指指针,*p是指指针所指物
const *p,限制的是(*p),*p不可以动,p可以动
* const p 限制的是(p),p不可以动,*p可以动
参考链接
- C语言const int *a和int*const a 的区别详解