一、指针的基本概念
1、通过指针来间接的访问内存
- 内存编号是从0开始记录的,一般用十六进制的数表示(以0开头的整数代表八进制,以0X开头的整数代表十六进制)
- 指针存放某个对象的地址
2、指针变量的定义: 数据类型 * 指针变量
int a=10;
int *p;
p = &a;
//以上的指针定义等价于如下的定义
int a = 10;
int *p = &a;
// a、c 为整型的指针变量,b为整型常量
int *a = nullptr, b = 10, *c = &b;
3、查看指针所占内存空间的大小
【注意】在32位操作系统(X86)下不管是什么类型的指针,其大小都是4个字节,因为其只是保存地址。
在64位操作系统(X64)下,指针下所占空间为8个字节。
// sizeof (int *) 可以查看整型指针所占内存的大小
cout << sizeof(int *) << endl;
4、空指针:不指向任何对象,在试图使用一个指针之前应该先检验是否为空。(指针变量指向内存中编号为0的空间)
注意:空指针指向的内存是不可以访问的。因为0~255之间的内存编号是系统占用的,因此不可以访问
// 空指针初始化指针变量的几种方法
int *p = nullptr; // 推荐用nullptr来初始化空指针,其为C++11新标准
int *p = 0;
int *p = NULL;
5、const 修饰指针
(1)、常量指针:
// 指针的指向可以修改,但是指针指向的值不可以修改
int a = 10;
const int *p = &a;
// p++; 正确
// (*p)++; 错误
cout << "*p= " << *p << endl;
(2)、指针常量
// 指针的指向不可以修改,但是指针指向的值可以修改
int b = 20;
int * const p = &b;
// p++; 错误
// (*p)++; 正确
6、指针和数组
(1)、一维数组:将数组的首地址赋给指针变量,然后通过指针来进行操作数组
int a[] = { 1,2,3,4,5 };
int *p = a;
cout << *(p+1) << endl; //通过指针访问数组的第二个元素
(2)、指针和多维数组,如下:
- 下标运算符([ ])的优先级高于解引用(*)的优先级,
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int s1 = 1, s2 = 2;
int s[] = { 1,2 };
// 整型指针数组:该数组的每个元素都是一个指针类型(int*),用来存放所指对象的地址
// p1先和[2]进行结合形成数组 p1[2],然后该数组元素的类型为指针类型(int *)
int *p1[2];
p1[0] = &s1;
p1[1] = &s2;
// *p1[0]和*p1[1]为解引用
cout << "p1 " << *p1[0] << " " << *p1[1] << endl;
// 指向含有2个整数的数组:p2为一个指针,它指向了一个含有2个元素的数组
// 括号的优先级最高,先定义指针p2,然后再和[2]结合,表示该指针指向含有两个元素的数组
int(*p2)[2];
p2 = &s;
cout << "p2 " << p2[0][0] << " " << p2[0][1] << endl;
cin.get();
}
运行结果如下所示
7、指针和函数
指针作为形参
void f1(int *p1, int *p2)
{
cout << *p1 + 10 << endl;
cout << *p2 * 100 << endl;
}
int main()
{
int a = 10, b = 20;
f1(&a, &b); // 将两变量的地址传给该函数
cin.get();
}
8、指针与数组、函数的一些总结
// p1 数组中有10个元素,元素的类型为指针类型。
int *p1[10]
// p2是一个指针,它指向一个数组,该数组中有10个整型元素
int (*p2)[10]
// f1函数的返回值是一个整型指针:int*
int *f1(int a, int b)
// f2是一个指向函数的指针,被指向的函数有两个整型的形参,且返回值为整型。
int (*f2)(int a, int b)