1.const在C和C++中的区别
C语言中以变量为主,C++中以常量为主
//示例
int main()
{
const int n=10;//C语言以变量为主
//int ar[n]={1,2};//error
int *p=(int *)&n;
*p=100;
int b=0;
b=n;
printf(" n = %d *p = %d b = %d \n",n,*p,b);
//n=100,*p=100,b=100
return 0;
}
int main()
{
const int n=10;//C++语言中以常量为主
int ar[n]={1,2};//ok
int *p=(int *)&n;
*p=100;
int b=0;
b=n;
cout<<" n = "<<n<<" *p = "<<*p<<" b = "<<b<<endl;
//n=10,*p=100,b=10
//虽然在内存中已经通过*p=100;将n的值变为100
//但在编译时遇见n是一个常变量,就拿10这个值将n替换掉
return 0;
}
2.const与指针的关系
int main()
{
int a=10,b=20;
int *p1=&a;//普通指针
p=&b;//ok
*p=100;//ok
const int *p2=&a;//指向为常性(解引用为常性)
//int const *p2=&a;等价
p2=&b;//ok
*p2= b;//error
int * const p3=&a;//指针变量自身为常性
p3=&b;//error
*p3=100;//ok
const int * const p4=&a;//指向(解引用)和指针变量自身都为常性
p4=&b;//error
*p4=100;//error
}
int main()
{
int a=10;
int *p1=&a;//ok
const int*p2=&a;//ok
int *const p3=&a;//ok
const int *const p4=&a;//ok
int *p5=(int*)&a;//ok
return 0;
}
3.常变量与指针
int main()
{
const int a=10;
int *p1=&a;//error
//a是一个常变量,拿普通指针指向a时,可以通过解引用*p1=100;来改变a的值,但是在C++中a的值不允许改变,因此编译错误。
const int*p2=&a;//ok
//a是一个常变量,拿指向为常性的指针指向a时,不可以通过解引用*p1=100;来改变a的值,并且在C++中a的值不允许改变,因此编译通过。
int *const p3=&a;//error
//a是一个常变量,拿指针变量自身为常量的指针指向a时,可以通过解引用*p1=100;来改变a的值,但是在C++中a的值不允许改变,因此编译错误。
const int *const p4=&a;//ok
//a是一个常变量,拿指向以及指针变量自身均为常性的指针指针指向a时,不可以通过解引用*p1=100;来改变a的值,并且在C++中a的值不允许改变,因此编译通过。
int *p5=(int*)&a;//ok 但不安全会造成程序二义性
*p5=100;
int x=a;//即使a的值在内存中变成了100,但是在编译时就拿10将a替换了,因此x的值还是10
return 0;
}
4.const指针相互赋值问题
兼容规则
能力强的指针赋值给能力收缩的指针
int main()
{
int a=10,b=20;//const int a = 10;也可以
const int *p=&a;//p是一个指向为常性的指针
int *s1=p;//error
//s1是一个普通指针,安全性发生了改变,p指针不能解引用,即*s1不能改变a的值,此时s1可以通过解引用改变p从而改变a,在整个过程中能力被扩展了,因此编译不能通过
const int *s2=p;//ok
//s2是一个指向为常性的指针,两者能力相同,可以编译通过
int * const s3=p;//error
//s3是一个指针变量自身为常性的指针,修饰的是指针自身不能改变,但是仍然能够通过解引用*s3来改变a的值,能力被扩展不安全,因此编译不能通过
const int * const s4=p;//ok
//s4是一个指针变量自身和指向(解引用)均为常性的指针,即不能通过解引用*s4去改变a的值,因此编译能通过
}
int main()
{
int a=10,b=20;
int * const p=&a;//p是一个指针变量自身为常性指针 指针自身不能改变但是指向可以改变
//p=&b;//error
int *s1=p;//ok
//int *s1=&a;
//*s1=100;//ok
//s1是一个普通指针,当s1=&b;时不会引导p也去指向b的地址,因为变量a的地址是一个常性地址,给s1以后相当于把变量a的地址给s1,即相当于int *s1=&a; 没有连带关系当s1=&b;时即当s1指向b时不存在必须导致p指向b
const int *s2=p;//ok
//const int *s2=*a;
//理解同上
int * const s3=p;//ok
//int * const s3=&a;
//理解同上
const int * const s4=p;//ok
//const int * const s4=&a;
//理解同上
}