C语言指针

指针基础知识

一、指针简介

指针是一个特殊的变量,是C语言里面一个变量(特殊的变量),也用于保存具体值,特殊之处在于指针用于保存内存中的地址,(内存地址是什么?内存是计算机中的存储部件,每个储存单元游固定唯一的编号,这里的编号就是内存地址)

二、获取地址

1、C语言中通过 & 操作符获取程序元素的地址

2、&可获取变量、数组、函数的起始地址

3、内存地址的本质是一个无符号整数(4字节或8字节)
在这里插入图片描述
三、指针定义的语法

指针定义语法:type*pointer

1、type—数据类型,决定访问内存时的长度范围

2、*—标志,意味着定义一个指针变量

3、pointer—变量名,遵循C语言命名规则
指针的命名例子在这插入图片描述
四、指针内存访问:*pointer

1、 指针访问操作符(*)作用于指针变量即可访问内存数据

2、指针的类型决定通过地址访问内存时的长度范围

3、指针的类型统一占用4字节或8字节
即:sizeof(type*)==4或8

例子显示(NULL专用的指针零值):在这里插入图片描述

深入理解指针与地址

一、初学指针的军规

1、type*类型的指针只保存type类型变量的地址

2、禁止不同类型的指针相互赋值

3、禁止将普通数值当作地址赋值给指针(指针保存的是有效地址)

二、通过指针实现两个值的交换

问题:怎么编写函数交换两个数的值(在函数内修改函数外的变量)
初学中我们常常使用这样的想法来改变一个变量的值:但是这样是错误的

在这里插入图片描述
但是通过指针可以实现在函数内修改函数外的变量:
在这里插入图片描述
因此可以通过指针访问地址直接改变两个变量的值

指针与数组

一、数组的一些事实

1、数组的本质的是一片连续的内存

2、数组的地址是什么?(数组的起始地址&a)

3、如何获取?(使用&操作符获取)

4、数组名可以看作一个指针,代表数组中0元素的地址 (a<=>&a[0])!!

二、指针指向数组时,可进行的指针运算
在这里插入图片描述
显然&a与a数值上是相等的,但是意义上完全不一样
1、&a代表数组地址,类型为:int*[5]
2、a代表的数组0号元素的地址,类型为int*
证明:
在这里插入图片描述
int a[]={1,2,3,4,5,};
int p = a;//指向a数组的0号元素,则a = p
a[i]<=>
(a+i)<=>(p+i)<=>p[i]
注意:int
类型+int类型=>int*类型

三、字符串拾遗

1、C语言中的字符串常量是char类型,一种指针类型
在这里插入图片描述
这里“D.T.Software”是全局数据区,是char
类型指针!

四、指针移动“组合拳” :int v=*p++

解读:指针访问操作符(*)和自增运算操作符(++)优先级相同
所以等价于:
int v = *p;
p++;

在这里插入图片描述
注意:数组名不能直接用来打“组合拳”
错误示例:
int a[]={1,2,3};
int v = *a++;//此处进行了a=a+1是错误的,不能更改a的数值!!

再论数组成为参数:
实际没有数组参数一说,最终数组形参会退化为指针,因此,不包含数组实参的长度信息,使用数组名调用时,传递的是0号元素的地址!
在这里插入图片描述
然后调用上面函数:(编译通过了,说明数组作为参数退化称为了指针)
*//int v = a++;的是编译错误的
说明了a[]参数退化成为了一个指针,一个与数组a0号元素地址相等的指针;
在这里插入图片描述

代码示例:
在这里插入图片描述
这里用*访问了“D.T.Software”,“D.T.Software”是一个指针,所以第一个打印的是第一个元素的值‘D’。后面连续判断,直到最后/0时,结束打印,最终打印出完整的“D.T.Software”!

指针与函数

一、函数的一些本质的事实

1、函数的本质是一段连续的代码(占用一片连续内存)

2、函数拥有返回类型和参数类型列表

3、函数名就是函数代码的起始地址(函数入口地址)

4、通过函数名调用函数,本质为指定具体地址的跳转执行
因此,可以定义指针,保存函数入口地址

例子:函数指针( Type func(Type1 a,Type1 b) ),与数组相似,函数名func就是函数入口地址,类型为Type(*)(Type1,Type2),与数组不同的是,函数中&func与func数值相同,意义也相同!

通过上述介绍,可以这样使用(定义指针,保存函数入口地址):
在这里插入图片描述
这里
pFunc = add;等价于pFunc = &add;相同地,pFunc = mul;也等价于pFunc = &mul;
pFunc(x,y)等价于(*pFunc)(x,y),编写代码时可以选择自己用的习惯的写法!

二、函数成为指针参数(定义指针函数,使用相同代码实现不同功能)
在这里插入图片描述
当使用calculate(a, 5,add);时就相当执行了1+…+5的操作。相同地,calculate(a, 5,mul);时就执行了1*…*5的操作。

三、注意事项

1、函数指针只是单纯的保存函数入口地址,只能调动函数,不能进行指针移动。

指针与堆空间

一、内存空间区域

1、全局数据区:存放全局变量,静态变量

2、栈空间:存放函数参数,局部变量

3、堆空间:用于动态创建变量(数组)
堆空间本质:备用的”仓库“,程序可在需要时从”仓库“申请使用内存(动态还)。当不需要使用时,需要立刻归还(动态还)

二、预备知识—void*

1、void类型(无长度信息)是基础类型,对用的指针类型是void*(无法获取内存中的数据)void类型可以保存任意类型的地址!但是无法用访问里面的数据!
在这里插入图片描述
显示错误:无法用*访问void里面的数据!

注意:void*类型的指针可以合法的直接赋值给其他具体数据类型的指针变量,可以和其他类型指针相互赋值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值