一、指针的定义与使用
1.指针的作用和定义
通过指针可以间接访问内存。指针的定义语法为:数据类型 * 指针变量名;
int a = 10;
int * p; // 定义指针p
p = &a; // 指针p记录a的地址
2.指针的使用
通过解指针(指针变量前加 *)的方式访问指针指向的内存。
int a = 10;
int * p; // 定义指针p
p = &a; // 指针p记录a的地址
*p = 100; // 解指针,并将p所指向的内存内容改为100
cout << a << endl;
cout << *p << endl;
100
100
请按任意键继续. . .
3.指针占用内存空间
指针存储的为地址信息,在32位系统中,内存地址需要4个字节进行存储;在64位系统中,内存地址需要8个字节进行存储。
int a = 10;
int * p; // 定义指针p
p = &a; // 指针p记录a的地址
cout << sizeof(p) << endl;
cout << sizeof(int *) << endl;
4
4
请按任意键继续. . .
注:float * 、double *等与int *所占用的内存空间一样(地址需要的内存空间一样)。
二、空指针与野指针
1.空指针
指向内存编号为零的指针,一般用于指针定义时的初始化。
int * p = NULL; // 定义空指针p
注:空指针的内存是不可以访问的。
2.野指针
野指针,也就是指向不可用内存区域的指针。如果对野指针进行操作,将会使程序发生不可预知的错误,甚至可能直接引起崩溃。造成野指针的三种情况:
- 指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,为避免这种情况造成的野指针,指针变量在创建时应当被初始化,要么将其设置为NULL,要么让它指向合法的内存。
- 指针指向的内存被释放了,而指针本身没有置NULL。指针指向的内存被释放了,而指针本身没有置NULL,此时p既不是NULL指针,它也不指向合法的内存块,因此成为野指针。所以在指针指向的内存被释放后,应该将指针置为NULL。
- 指针超过了变量的作用范围。即在变量的作用范围之外使用了指向变量地址的指针。这一般发生在将调用函数中的局部变量的地址传出来引起的。这点容易被忽略,虽然代码是很可能可以执行无误,然而却是极其危险的。局部变量的作用范围虽然已经结束,内存已经被释放,然而地址值仍是可用的,不过随时都可能被内存管理分配给其他变量。
三、const修饰指针
1.常量指针:const 数据类型 * 指针变量名
const修饰的是指针,指针指向可以变,但是不可以通过解指针的方式改变指向内存的值。
int a = 10;
int b = 20;
const int * p = $a;
// 指针指向可以修改
p = &b;
// 指针指向地址的内容不可修改
*p = 100; // 该行是错误的
2.指针常量:数据类型 * const 指针变量名
const修饰的是常量,指针指向不可以变,但是可以通过解指针的方式改变指向内存的值。
int a = 10;
int b = 20;
const int * p = $a;
// 指针指向不可以修改
p = &b; // 该行是错误的
// 指针指向地址的内容可修改
*p = 100;
3.const 数据类型 * const 指针变量名
const既修饰指针也修饰常量,指针指向不可以变,也不可以通过解指针的方式改变指向内存的值。
int a = 10;
int b = 20;
const int * p = $a;
// 指针指向不可以修改
p = &b; // 该行是错误的
// 指针指向地址的内容也不可修改
*p = 100; // 该行是错误的
四、指针与数组
通过指针可以访问数组中的元素。
int a[5] = {1,2,3,4,5};
int * p = a;
// 获取数组的长度
int len = sizeof(a)/sizeof(a[0]);
// 通过指针打印数组
for(int i = 0; i < len; i++)
{
cout << *p << endl;
p++; // 指针p的数据类型是int *,因此在自增时其指向的地址增加4个字节
}
1
2
3
4
5
请按任意键继续. . .
五、指针与函数
在函数调用时,一般变量使用值传递的方式实现实参与形参的值传递,此时形参的改变不会影响实参。在函数调用时,也可进行地址传递,从而实现函数体内改变函数外的变量值。
#inclued <iostream>
using namespace std;
void swap(int * p1, int * p2);
int main()
{
int a = 10;
int b = 100;
swap(&a, &b);
cout << a << endl;
cout << b << endl;
system("pause");
return 0;
}
void swap(int * p1, int * p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
注:函数传递数组参数时使用地址传递。