首页
论坛
课程
招聘
[基础知识] [分享]C语言基础八-指针
2021-4-24 23:11 1558

[基础知识] [分享]C语言基础八-指针

2021-4-24 23:11
1558

指针的定义

指针的含义包含3个方面:变量、地址、内存宽度。

  • 指针是一个变量,x86占4个字节,x64占8个字节
  • 指针的值是一个内存地址,指向内存的某一个地方
  • 指针明确了指向内存的宽度,通过指针的类型确定

在定义指针的时候,*和类型结合,表示指针的类型;在使用指针的时候, *和指针结合,表示解引用。
指针的初始化,可以让指针指向某个变量的地址,也可以让指针指向一个分配的内存或者字符串常量,还可以指向NULL。

取地址运算符&和解引用运算符*

  • &:取址,取变量的地址,reference,引用
  • **:取内容,取地址对应内存中的内容,dereference,解引用
  • &和**互为逆运算
  • 定义一个指针p,*p表示通过指针,即指向的内存地址,找到对应的内存和里面存放的数据,进行读取或者修改操作
  • 解引用运算符后面必须是指针,不能为无效的内存,也不能为NULL,否则程序会运行崩溃

指针的数据类型

定义一个指针:
sizeof(p)=4or8(指针类型的变量长度为4或者8)
sizeof(*p)=指针所指类型的长度

 

void* p;

  1. 可以接受任何类型的指针
  2. 赋值给其他类型指针需要强转
  3. 不能进行解引用运算,必须先转换
  4. 不能进行加减算术运算

void类型,没有指定内存长度,其他类型指针隐式转换成该类型,不能p解引用取值,需要先转特定类型再取值
字符指针
既可以指向字符,也可以指向字符串,其实是字符串首个字符的地址
判断字符指针指向字符还是字符串,需要程序员自己确定
字符单引号,字符串双引号

指针的运算

指针支持加减运算,不支持其他算术运算。对于指针p,指针的加法运算p+n,p向前移动的距离不是n个字节,而是n个指针所指类型的单位长度,即nsizeof(p),减法运算与此类似。

数组和指针

数组名是一个常量指针,指向数组的首地址,指针和数组名可以互相通用。

1
2
3
4
5
6
7
int nArray[3];
//第i个元素
a[i];
*(a+i);
//第i个元素的地址
a+i;
&a[i];

常量指针与指针常量

1
2
3
4
5
6
int* const p;
//常量指针,p是一个常量指针,不能修改,指向的内存可以修改
const int* p;
//指针常量,p是一个指针,指向的内存是常量,不能修改,p本身可以修改
 const int* const p;
//p是一个常量指针,指向的内存也是常量,都不能修改

指针数组与数组指针

1
2
3
4
//指针数组,存放指针的数组
int* a[10];
//数组指针,存放的是地址,指向一个拥有10个元素的数组
int(*a)[10];

函数指针与指针函数

函数指针

  1. 函数名,就是函数的地址。
  2. 函数的签名,包含函数的返回值类型,参数类型,参数个数。
  3. 如果一个指针变量,存放的是函数的地址,那么就把这个指针叫做函数指针,函数指针的类型由对应的函数签名来决定。

定义函数指针的两种方法:

  1. 直接用函数的签名定义函数指针
  2. 用typedef定义出函数指针的类型,再用指针类型定义函数指针

vs2019中,为函数指针赋值,函数名func等同于&func。

指针函数

  1. 返回值是指针的函数
  2. 指针函数不能返回局部变量的地址,指针或者引用,因为局部变量的地址会随着函数调用结束被自动释放,指针会成为一个野指针
  3. 可以返回堆上的内存

二级指针,指针的指针

如果指针做实参,那么传实参的指针就必须使用二级指针,要在函数中改变指针的值,就必须传指针的指针。
为指针分配堆内存:

1
2
3
4
5
6
7
8
char *p = (char*)malloc(128);
if(p==NULL)
{
return -1;
}
memset(p,0,128);
free(p);
p = NULL;

关于指针的复杂声明:

  • int* a[10];指针数组
  • int(*a)[10];数组指针
  • int* a(int);指针函数
  • int(*a)(int);函数指针
  1. a和*结合,a是一个指针
  2. a和[]结合,a是一个数组
  3. a和()结合,a是一个函数

为什么要使用指针

  1. 通过内存地址直接操作内存,性能高
  2. 函数传参时,传指针比传值可以减少拷贝,效率高
  3. 复制指针之后,解引用取出数据,无论在时间还是空间上,都比直接复制及访问数据高效
  4. 指针可能跑飞,破坏其他部分的程序数据,造成内存泄露
  5. 传引用比传指针安全
    指针在声明的时候需要初始化,如果没有初始化,任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,会随机的指向任何一个地址,即野指针,访问野指针会造成不可预知的后果。

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班火热招生!!

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 197
活跃值: 活跃值 (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tfrist 活跃值 2021-5-4 13:52
2
0
要想学好C的指针 一定要学好汇编!
游客
登录 | 注册 方可回帖
返回