指针类型
写在前面:
存储另一个变量的地址的变量称为指针。指针被称为“指向”它们存储的地址的变量。
- 对于C ++程序,计算机的存储器就像一连串的存储单元,每个存储单元大小为一个字节,每个存储单元都有一个唯一的地 址。这些单字节存储器单元的排序方式允许大于一个字节的数据表示占用具有连续地址的存储器单元。
- 其实我们知道,在真正的意义上,变量可以被解释为计算机内存中可通过其标识符(其名称)访问的位置
& 取地址符 取得变量地址(实际内存中的变量在运行之前是不可知的)
*解引用符 访问指针所指向的内容
1 void* 空指针
-
“无效指针” -- 可以指向任何类型
【void* 指针 的类型是一种特殊类型的指针。在C ++中,void表示缺少类型。因此,void指针是指向没有类型的值的指针(因此也是未确定的长度和未确定的解除引用属性)。通过能够指向任何数据类型,从整数值或浮点数到字符串,
这为void指针提供了极大的灵活性。作为交换,它们有一个很大的局限性:它们指向的数据不能直接解引用(这是合乎逻辑的,因为我们没有要取消引用的类型),因此,void指针中的任何地址都需要转换为某些地址在被解除引用之前指向具体数据类型的其他指针类型。】
2 空指针 (指针为空)
指针值为空;
int *p=nullptr;
int *q=NULL;
3 空悬指针(无效指针)&& 野指针
空悬指针:指向已经销毁的对象或已经回收的地址
野指针:没有初始化的指针
例子:
char * ptr; // 野指针
char * ptr_=(char* )malloc(sizeof(char)*100);
free(ptr_);
4 函数指针&指针函数
函数的首地址也以存储在某个函数指针变量中。这样,就可以通过这个函数指针变量来调用所指向的函数了
这里我总结出几条结论:
(1)函数名是一个函数指针常量,而声明的funpointer、funApointer是函数数指针变量
(2)void (*funp)(int) ; //声明一个指向同样参数、返回值的函数指针变量。
(3)funp=&myfunc; //将myFun函数的地址赋给funP变量
(4)因此函数的调用方式便有了两种: 函数名,函数指针
5 多重指针
二维指针(指向指针的指针)
三维指针
NULL
- 赋为 NULL 值的指针被称为空指针
NULL 指针是一个定义在标准库中的值为零的常量
引用
引用和初始化的对象是同一种东西,地址相同,因此可以理解为一种别名
int main()
{
int a=1;
int &b = a;
int c=2;
b = c;
int &d = b;
cout << a << b << c << d << endl;
system("pause");
return 0;
}
//输出结果: 2,2,2,2
关于指针&引用在函数形参传递
void func1(Class* obj)
{
obj->xxx(); // 指针
}
void func2(Class obj)
{
obj.xxx(); //形参
}
void func3(Class& obj)
{
obj.xxx(); //引用 (引用速度最快,通常不用声明变量)
}
函数重载的同名问题
例子1:
C++编译器认为以下两个函数的签名相同,因此不能同时出现
void imag(const double& im) { . . . } / / 不允许同时出现
void imag(const double im) { . . . }
例子2:
const被视为函数签名的一部分,因此允许以下情况共存
void imag(const double& im) const { . . . } / / 允许同时出现
void imag(const double im) { . . . } // 不能添加const