- Difference between const char *p, char * const p and const char * const p
1.const
const是constant的简写,只要一个变量前面用const来修饰,就意味着该变量里的数据可以被访问,不能被修改。也就是说const意味着“只读”。任何修改该变量的尝试都会导致编译错误。const是通过编译器在编译的时候执行检查来确保实现的(也就是说const类型的变量不能改是编译错误,不是运行时错误。)所以我们只要想办法骗过编译器,就可以修改const定义的常量,而运行时不会报错。
规则:
- const离谁近,谁就不能被修改;
- 因为常量在定义以后就不能被修改,所以使用const定义变量时必须初始化。
#include <stdio.h>
int main(void)
{
int i = 10;
int j = 20;
const int *ptr = &i;
printf("ptr: %d\n", *ptr);
*ptr = 100; /* error: object pointed cannot be modified using the pointer ptr */
ptr = &j; /* valid */
printf("ptr: %d\n", *ptr);
return 0;
}
2.const point
声明指针时,可以在类型前或后使用关键字const,也可在两个位置都使用。三种定义形式如下:
- Pointer to constant
- const int *ptr;
- int const *ptr;
- Constant pointer to variable
- int *const ptr;
- constant pointer to constant
- const int *const ptr;
各个含义如下:
- const int * pOne;
- You cannot change the value pointed by ptr, but you can change the pointer itself.
- int * const pTwo;
- You cannot change the pointer p, but can change the value pointed by ptr.
- const int *const pThree;
- You can neither change the value pointed by ptr nor the pointer ptr.
加深记忆记住三句话:
指针和 const 谁在前先读谁 ;
*象征着地址,const象征着内容;
谁在前面谁就不允许改变。
例如:
int const *p1 = &b; //const 在前,定义为常量指针
int *const p2 = &c; // *在前,定义为指针常量
常量指针是指指向常量的指针,顾名思义,就是指针指向的是常量,即,它不能指向变量,它指向的内容不能被改变,不能通过指针来修改它指向的内容,但是指针自身不是常量,它自身的值可以改变,从而指向另一个常量。
指针常量是指指针本身是常量。它指向的地址是不可改变的,但地址里的内容可以通过指针改变。它指向的地址将伴其一生,直到生命周期结束。有一点需要注意的是,指针常量在定义时必须同时赋初值。
案例1:指针b指向的地址内容不能修改,而指针b可以指向其他地址。
#改变指针b指向地址的内容
int main()
{
int a = 2;
int const *b = &a;
*b = 3; //报错:expression must be a modifiable lvalue
printf("albert:%d\n",a);
}
----------------------------------------------------------------------------
#改变指针b的指向
int main()
{
int a = 2;
int b = 3;
int const *c = &a;
printf("albert:%p\n", c);
c = &b;
printf("albert:%p\n",c);
}
案例2:指针指向的地址不可以重新赋值,但内容可以改变。
int main()
{
int a = 2;
int b = 3;
int *const c = &a;
printf("albert:%p\n", c);
c = &b; //报错:expression must be a modifiable lvalue
printf("albert:%p\n",c);
}
--------------------------------------------------------------------------
int main()
{
int a = 2;
int b = 3;
int *const c = &a;
*c = 4;
printf("albert:%d\n",*c); //4
}
3.Difference between pointer and array in C
As we have seen, when we declare an array, a contiguous block of memory is allocated for the cells of the array and a pointer cell (of the appropriate type) is also allocated and initialized to point to the first cell of the array. This pointer cell is given the name of the array. When memory is allocated for the array cells, the starting address is fixed, i.e. it cannot be changed during program execution. Therefore, the value of the pointer cell should not be changed. To ensure that this pointer is not changed, in C, array names may not be used as variables on the left of an assignment statement, i.e. they may not be used as an Lvalue. Instead, if necessary, separate pointer variables of the appropriate type may be declared and used as Lvalues.
实例:
#include <stdio.h>
int main()
{
int a[] = { 1,5,10,20 };
int b = *a++; //*a++ 等同于*(a++)
printf("b = %d\n",b);
}
如上所示,编译报错:由于数组名是常量指针,所以不能执行a++,进行修改。
参考资料:
http://ee.hawaii.edu/~tep/EE160/Book/chap7/subsection2.1.3.2.html
https://www.geeksforgeeks.org/difference-const-char-p-char-const-p-const-char-const-p/