一.const关键字的用法
定义一个常量的方法有两种,一种是通过宏定义来创建一个常量,另一种就是通过const修饰来创建一个常量。区别就是宏定义是在预处理阶段将内容进行替换。
通过gcc将上图文件输出成预处理之后的文件发现,在预处理阶段将内容替换。
对于宏定义编译器是不会做类型检查,可能会出现问题不易发现。而const常量有具体的类型,在编译期会执行类型检查。
1.利用const修饰普通变量
#include<iostream>
using std::cout;
using std::endl;
int main()
{
//常量在定义时必须要初始化,因为常量时不能进行赋值操作的
const int num1=100;
//const在数据类型的前后无所谓
int const num2=200;
cout<<"num1="<<num1<<endl;
cout<<"num2="<<num2<<endl;
return 0;
}
2.利用const来修饰指针
有几个易混淆的概念,分别是指针常量和常量指针,函数指针和指针函数,数组指针和指针数组。
指针常量和常量指针的区别:
指针常量,表示指针是常量,也就是地址是常量
常量指针,表示指向常量的指针,也就是指针的指向是”不可改变的“
#include<iostream>
using std::cout;
using std::endl;
int num = 100;
int a = 50;
int main()
{
//常量指针和指针常量
//指针常量,表示指针是常量,也就是地址是常量
int* const pnum = #//只需看const后面修饰的是什么,什么就是常量
*pnum = 10;
//pnum = &a;这种是会报错的,表达式的左值必须是可修改的值
puts("------------------------常量指针----------------------\n");
cout << "pnum的值=" << *pnum << endl;
cout << "pnum的地址=" << pnum << endl;
cout << "num的地址=" << &num << endl;
puts("-----------------------指针常量-------------------------\n");
//常量指针,表示指向常量的指针,也就是指针的指向是”不可改变的“
int const* pnum1 = #
pnum1 = &a;
//*pnum1 = 10;这种是不允许的
cout << "pnum1的值=" << *pnum1 << endl;//还是可以通过改变指针的值,来改变指针的指向
cout << "pnum1的地址=" << pnum1 << endl;
cout << "num的地址=" << &num << endl;
return 0;
}
指针函数和函数指针:
指针函数:本质还是一个函数,只不过这个函数是一个指针类型的函数,也就是返回值是一个指针。
int* func()
{
//指针函数
int* a = #
return a;
}
函数指针:本质上是一个指针,只不过是一个指向函数的指针。我们知道在程序执行过程中每个函数也是对应内存中的某个地址,所以通过函数指针来指向某个函数。
#include<iostream>
using std::cout;
using std::endl;
int num = 100;
int* func()
{
//指针函数
int* a = #
return a;
}
int main()
{
// int* (*pfunc)()是函数指针
int* (*pfunc)() = func;
cout << "func()=" << *(pfunc)() << endl;
return 0;
}
数组指针和指针数组
同理数组指针:本质上还是指针,只不过是指向数组的指针。
指针数组:本质上是一个数组,只不过是这个数组存储的是一个指针类型。
#include<iostream>
using std::cout;
using std::endl;
int arr[5] = {1,2,3,4,5};
//数组指针
int(*parr)[5]=&arr;
int main()
{
//数组名代表数组的首地址也就是等价于&arr[0]的值
cout << "arr=" << arr << endl;
//因为数组的存贮是连续存储并且arr在内存中没有分配空间,
// 只对数组a的各个元素分配了存储空间,此处数组名字arr显然不是普通的变量,&arr也不代表所取a的存储地址。
cout << "&arr=" << &arr << endl;
//&arr虽然和arr的值一样,但是意义却有很大差别,此时,&arr数值上等于整个数组的起始位置地址,含义上代表整个数组所占内存的大小,
// 因为它的进阶单位是整个数组的字节长度,(&arr + 1)等于的是数组结束之后的下一段的起始位置地址。
cout << "&arr+1=" << &arr + 1 << endl;
cout << "*parr=" << *parr << endl;
cout << "**parr=" << **parr << endl;
return 0;
}
对于数组指针:int(*parr)[5]=&arr;要知道指针到底指向的是什么。
对于指针数组,最经典的就是c语言中的字符串数组,数组中的每个指针指向字符串的首地址。