指针究竟是什么
- 指针是一类特殊的变量,他保存的不是一般数据的值,而是程序中另一对象在内存中的地址
我们先通过一个小程序看一看指针如何工作1
2
3
4
5
6
7
8
9
10
11#include <iostream>
using namespace std;
int main(){
int n = 123,m = 456;
int *p = &n;
cout<<"&n:"<<&n<<endl;
cout<<"&p:"<<&p<<endl;
cout<<" p:"<<p<<endl;
cout<<"*p:"<<*p<<endl;
return 0;
}
从运行结果可以看出下面几点:
- p本身是有一个地址的且地址为 &p
- p的值是另一个变量n的地址 &n
- *p所表示的意思是地址为 p 的内存中所存的值 n
- 即本段程序中共涉及到2个地址,一个是 n 的地址,一个是 p 的地址,我们用一张图来表示他们的关系
指针的初始化
被具有相同类型的对象初始化
1
2int i = 10;
int *p = &i;由另一个同一类型的指针初始化,这时两个指针指向同一地址空间
1
int *p1 = p;
通过直接分配内存地址得到初值
1
int *p2 = new int;
指针也可以没有类型,通用指针的定义,这样的指针可以指向任一对象
1
void *p3
指针的运算符
定义指针的目的事通过指针变量间接的访问变量
- *:取指针值运算符。通过指针所指内存单元的地址间接的访问对应的存储单元。若指针变量p指向变量a,则 *p的运算结果为变量a的值
&:取地址运算符。返回变量对应的存储单元地址,若a为int变量,p为int型指针变量,则 p = &a表示将a的存储单元地址赋给p。
用一个程序验证一下:1
2
3
4
5
6
7
8
9
10
11
12
13#include <iostream>
using namespace std;
int main(){
int a = 100;
int *p,*p1,*q;
p = &a;
p1 = p;
q = NULL;
cout<<"a="<<a<<","<<"*p="<<*p<<","<<"p="<<p<<endl;
*p1 = 200;
cout<<"a="<<a<<","<<"*p="<<*p<<","<<"p="<<p<<endl;
cout<<"*p1="<<*p1<<","<<"p1="<<p1<<endl;
}运行结果
指针与数组的关系
- 数组名和指针在引用数组元素和取他们的地址方面可以相互转换,但两者有一个重要的不同点
数组是在定义时就分配好内存空间的,因此数组名是一个地址常量,在程序中不能将数组名作为变量为其赋值,而指针是一个变量,可以多次赋值
我们通过一个程序看一下他们的关系1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <iostream>
using namespace std;
int main(){
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *pa = a;
int i = 3;
cout<<"a[i] :"<<a[i]<<endl;
cout<<"*(pa+i):"<<*(pa+i)<<endl;
cout<<"*(a+i) :"<<*(a+i)<<endl;
cout<<"&a[i] :"<<&a[i]<<endl;
cout<<"a+i :"<<a+i<<endl;
cout<<"pa+i :"<<pa+i<<endl;
}运行结果
易重要的和易混淆的概念
- 为什么要对指针初始化?
定义了指针变量后,系统会为其分配一个内存空间,若没有赋值则此内存区域的内容是随机的,也就是指针随机指向一个内存单元。你想想如果你对一个随机的内存空间进行写操作,会怎样! - 指针的运算
指针 + 整数 = 指针
指针 - 指针 = 整数 //同类行的指针相减表示两个基类型变量的个数
指针 + 指针 = ???? //不可以 new、 new[]、 delete、 delete[]有什么区别
1
2
3
4int *p = new int(3) // 为p分配了一个整形变量的存储区域并初始化为3
int *p1 = new int[20] // 分配20个整形变量的区域给p1
delete p //释放有new申请的空间
delete[] p1 //释放由new[]申请的空间c++程序中动态分配的内存不会被自动释放
- 指针函数和函数指针含义相同吗?
完全不同!
指针函数:若一个函数返回的是一个地址,则称该函数为指针函数。格式是 数据类型 函数名(参数列表)
函数指针:指针变量指向一个函数的入口地址,格式为 数据类型 (函数指针变量)(参数列表)
函数指针的用法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <iostream>
using namespace std;
int cul(int (*pf)(int,int), int x, int y){
return pf(x,y);
}
int add(int x,int y){
return x+y;
}
int sub(int x,int y){
return x-y;
}
int main(){
int a=10,b=20;
cout<<a<<"+"<<b<<"="<<cul(add,a,b)<<endl;
cout<<a<<"-"<<b<<"="<<cul(sub,a,b);
}
- 常量指针、指针常量、指向常量的指针常量有什么区别
常量指针:表示指针指向的是一个常量,格式:const 类型 指针变量 或 类型 const 指针变量1
2
3
4int i;
const int *p = &i;
*p = 10; //错误
i = 10; //正确
指针常量:表示所定义的指针是一个常量,只能在定义的时候初始化1
2
3int i,j;
int * const p = &i;
p = &j;//错误
指向常量的指针常量:格式为 const 类型 * const 指针常量1
2
3
4
5int i,j;
const int * const p = &i;
*p = 10;//错误
p = &j;//错误
i = 10;//正确