C语言之指针

什么是指针:

指针是一种数据类型(无符号整数,这种整数代表了内存的编号),使用它可以定义的变量叫指针变量(简称指针,这种变量占用4|8字节内存大小)。

为什么使用指针:

1、函数之间共享变量:全局变量可能会名字冲突不可过多使用。 函数之间传参是值传递的,因此不能共享变量。函数之间的命名空间是独立的,但是存储空间是统一,可以把存储的地址在函数之间传递,达到共享的目的。

2、堆内存无法取名字(标识符无法与内存建立映射关系),只能与指针配合使用。

3、由于函数之间采用值传递进行传参(内存拷贝),当传递字节数较多的变量时效率会很低,如果只传递变量的地址只需要4字节(64系统8字节);

如何使用指针:

定义指针变量:类型* 指针变量名;

1、指针变量的用法与普通变量不同,为了区分它一般以p结尾

2、指针变量不能连续定义,一个只能定义出一个指针变量。
short
p1,p2,p3; // p1是指针,p2,p3是short变量
short *p1,*p2,*p3; // p1,p2,p3都是指针变量

3、指针的类型决定了通过指针访问内存读取几个字节,int类型读取4字节,double类型读取8字节,char类型读取1字节。

4、指针变量的默认值是随机的,为了安全一定要初始化,一般初始化为NULL(空指针)。

赋值:变量名_p =地址编号;
指针变量必须存储一个有意义的内存编号,否则可能会造成段错误(非法访问内存)。
p = & num; // 将num的内存地址赋值给p
p = malloc(4); // 从堆内存分配两个字节,并把首地址赋值给p

取值:*p;
根据指针变量中存储的值访问内存(解引用)。
具体访问多少个字节由指针的类型决定。

使用指针要注意的问题

空指针:在C语言一旦对空指针进行解引用就会出现段错误。
在大多数系统下NULL就是0地址,由于操作系统把这个地址当作了复位地址(当操作系统重启时,会跳转到这个地址执行,所以它里面存储的是操作系统用来重启的数据),所以操作系统禁止访问这块内存,一旦解引用就会出现段错误。

如何杜绝空指针造成的段错误:使用来历不明的指针前要先判断是否是空指针。

if(NULL == p)

野指针:指向的内存不明确,这种指针叫野指针(野指针不代表就是错的,也有可能是正确的)。

使用野指针不一定会出错,但这也正是它危险的地方,因为无法证明,也无法判定,而且危险是潜在的。

使用野指针的后果

1、一切正常
2、段错误
3、脏数据

如何避免使用野指针:由于无法判断是否是野指针,因此只能从源着手,不制造野指针是每个程序员应尽的职责。

如何避免产生野指针:
1、定义指针时初始化。
2、不获取局部变量的地址(在函数执行完后局部变量就会被释放)。
3、指针指向的资源被释放后,指针要及时赋值为空。

指针的运算:

指针变量里存储的就是整数,所以整型变量能够使用的运算符,指针变量都能使用,但对指针变量的所有运算不是都有意义的。

指针 + n =指针+宽度n // 指针向后移动n个元素
指针 - n = 指针-宽度
n // 指针向前移动n个元素
指针 - 指针 = (指针-指针)/宽度 // 计算出两个指针之间相隔多少个元素。

%p 是以十六进制方式显示指针变量的值。

指针与数组

数组名就是个指针,是一种特殊指针(常指针),不能修改。
数组名与数组的首地址是对应关系,而指针是指向关系。
数组名可以使用指针的语法,指针也可以使用数组的语法。

arr[i] <=>*(arr+i)

当数组作函数的参数时,它就蜕变成了指针,在函数中无法计算出数组的长度,因此需要再添加一个参数把数组的长度传递过来。

指针与const配合

const int* p; // 保护的是指针指向的内存,不能通过指针去修改内存的值。

int const *p; // 同上

int* const p; // 保护的是指针变量,不能修改指针变量的值。

const int* const p; // 既保护的是指针变量又保护指针变量指向的内存。

int const* const p; // 同上

下面为一段指针基础用法的代码

#include <stdio.h>
int main(void)
{
	int num = 10;
	int* p = NULL; // 定义一个指针p
	printf("%d", num); 
	p = &num; // 将num的地址赋值给指针p,此时*p <=> num,*p == 10
	printf("%d", *p); 
	*p = 100; // 此时num == 100;
	printf("%d %d", *p, num);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值