C语言 指针的基本知识

内存的单位:
bit 一个bit位能存储1个二进制 内存的最小单位。
1byte = 8bit,一次性使用的最小单位,操作系统会为每个字节分配一个编号(天然按位置排列)。
1kb = 1024byte
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb
1pt = 1024tb
什么是指针:

指针变量的取值范围取值0~4G

指针是一种数据类型(无符号整数,代表了内存编号)

使用它可以用来定义变量(与int、long一样),
与int、long不同的它存储整数代表了内存的编号,
通过这个变量可以访问对应编号的内存。

为什么使用指针:

1、堆内存无法取名字(无法使用标识符与堆内存建立联系),必须配合指针。

2、函数之间的参数是值传递(内存拷贝),使用指针可以优化参数的传递效率
(需要对变量进行保护)。因为C语言采用的是值传递(内存拷贝),
会随着变量字节数的增加而降低运行效率
而传递变量的地址永远只拷贝4或8字节
void func(const int* p);
但使用指针变量的值可能会被修改,可以配合const		

3、函数之间是相互独立的,有时协同配合需要共享变量
(全局变量过多会造成命名冲突,不会被释放浪费内存),
函数之间传递变量的地址可以达到共享变量的效果。

如何使用指针:

定义:类型* 变量名_p;  
	1、指针变量与普通变量一样默认值不确定,一般初始化为NULL。
	2、指针变量的用法与普通变量不同,一般以p结尾加以区分。
	3、指针变量的类型决定了通过指针变量访问内存时访问几个字节。
	4、指针变量不能连续定义(一个*只能定义出一个指针变量):
		int* p1,p2; // p是指针,p2是int类型变量
		int *p1,*p2; // p1和p2都是指针变量
赋值:指针变量 = 内存编号。
		变量名_p = 地址;
	1、类型要正确。
	2、内存编号要能够访问,如果编号错误可能会造成段错误。
	3、void*可以与任意类型指针进行自动转换(C++中不行)
	4、要保障地址与物理内存有对应关系(映射过),否则有段错误。
	int* p = malloc(4);
	int* p = # // 引用内存
访问:*指针变量 //解引用----访问指针变量
	1、根据指针变量中存储的内存编号去访问对应的内存。
	2、如果之前赋值的内存编号有误,这个步骤会出现段错误。
	3、访问的字节由指针类型决定。
	int* p = #
	*p <=> num;

使用指针要注意的问题

1.空指针:
变量指针的值等于NULL,这种指针叫空指针。
不能对空指针解引用,一定会出现段错误。
当操作重启时会跳转NULL地址,进行重启,因此NULL存储操作系统用于重启的数据。
NULL在C语言中是一种错误标志,如果函数的返回值是指针类型,
结果一旦NULL表示函数执行出错或失败。
如何避免空指针造成的段错误?
使用来历不明(函数的参数)的指针前先进行检查,if(NULL == p)。

2.野指针:指针变量的值不确定,使用野指针不一定会出错。
int* p; // 野指针
使用野指针的后果:
	1、一切正常。
	2、脏数据。
	3、段错误。	
注意:野指针是无法分辨的,所以比空指针危害更。
如何避免野指针造成的错误?
所有的野指针都人制造出来的,只要人人都不制造野指针就会有野指针造成的错误。
	1、定义指针变量时一定要初始化。
	2、指针变量所指向的内存初始释放后要及时赋值为空(堆内存)。
	3、不返回局部变量的地址。

指针的运算

指针变量中存储的就是整数,因此为整型数据能使用的运算符指针变量基本都能使用
,但不是所有运算都有意义。
指针+整数 = 指针+宽度*整数
指针-整数 = 指针-宽度*整数 // 指针进行前后移动
指针-指针 = (指针-指针)/宽度 // 两个指针之间相隔多少个元素
指针 >、<、<=、>= 指针 可以判断两个谁在前谁在后。

数组与指针

1.数组名就是个特殊的地址,也能当指针使用,数组名是个常量
(数组名与数组第一个元素的首地址是对应关系,普通指针是指向关系)。
2.数组名可以使用指针的解引用,而指针变量也可以使用数组的[];
arr[i] <=> *(arr+i)。
3.数组当函数的参数就脱变成了指针变量,长度丢失,安全性也变小
void func(int * const arr,size_t len);

指针与const的配合使用:
const int* p
int const *p;
int * const p;
const int * const p;
int const * const p;

const 与 指针

const int * p; // 不能通过解引用去修改指针所指向的内存的数据
	1、保护函数的参数
	2、当指针指向的是只读数据,也应该加上const防止出现段错误。
int const * p; // 同上

int* const p; // 不能修改指针变量的值
	可以防止指针变量意外变成野指针

const int* const p; // 既保存指针所指针的内存,也保护指针变量
int const * const p; // 同上

指针的高级应用:

数组指针与指针数组:

1.数组指针(指针):专门用来指向数组的指针。
int arr[10];
int (*p)[10] = arr;
int* p = &num;

void func(int I,int J,int(*arr)[J])  //二维数组 函数传参使用数组指针


2.指针数组(数组):一个数组里存储的数据类型是指针。
				把无序的离散数据,归纳到一起。
int* arr[3]; <=> int *p1,*p2,*p3;

3.二级值针: 指向指针的指针
4.函数指针: 指向函数的指针(不能解引用)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值