一丶 指针的概念
首先要知道何为指针,指针就是有效存放地址的变量。指针就是地址,地址就是指针。
1.1丶地址
地址就是储存变量的编号。例如:我们住酒店,101,102,103这些房间号都是变量地址,而把酒店前台人员比作指针变量,前台就可以通过查看房间号来确认乘客信息,好比通过内存地址获取内存中的数据。
我们访问地址有两种方法:直接访问和间接访问。
直接访问:就是用变量名对变量进行访问叫直接访问。
间接访问:首先将变量的地址储存在另一个特殊的变量中,然后同过访问这个特殊的变量间接访问变量地址。
1.2丶指针变量
C语言中,定义一个变量时,一定要先确实它的类型,在指针中也不例外,我们需要先确定指针的类型,什么变量的指针就需要用什么类型的指针储存。
我们对指针变量的一般形式为:
类型说明符 *变量名
类型说明符就在我们一开始就要确定的数据类型,*在这里面就表示这是一个指针变量,变量名就是定义的指针变量名。
例如:int *p;表示p指向一个整形变量。
需要注意,一个指针变量只有指向一种数据类型,如果一个指针变量同时指向不同数据类型,由于不同数据类型所占有的字节数不同,因此程序容易发生错误。
指针变量的初始化:
以上两种方式都是将变量a的地址放到指针变量p中
这个方法就是错误的,我们它为野指针。野指针就是指针变量指向一个无效的内存空间的指针,上面这个代码就是指针定义后未初始化就将100随便放入了一个地址,这种做法是很危险的,非法的。
指针与整数的运算:
指针的+1和-1,不是单纯的+1和-1,而是加一个所指变量的字节数。
不多说,直接上代码。
在int类型里面pa+1相当于加了4,因为在int占四个字节。
由于char只占一个字节,所以pb+1就是+1。
二丶指针与数组
这里我们定义了一个数组arr,和指针变量p。
如果一个变量存放了数组的起始地址,那么该变量为指向数组和指针变量
例如:
在C语言中数组名表示数组的首地址。
所以以上两个句式是相等的。
通过指针引用数组元素
1.当p已经定义为指向arr的指针变量时,arr[1]和p[1]就是相等的。
2.在以上基础的前提下表示地址时,有多种表示方法,例如arr[1]可以用&arr[1] ,&p[1] ,p+1,arr+1,其意义是相同的。
3.同理要对数组元素的引用时,也可以用多种方法,例如arr[1]可以用p[1],*(p+1),*(a+1)来表示。
4.在指针变量和数组名的引用中,指针变量也可以取代数组名,但是数组名不可以取得指针变量来操作,因为在C语言中数组名是一个常量。例如:我们可以使用p++来取得数组名,但是不能用arr++来取代指针变量,因为arr++中arr已经是个常量,arr++只是个自增运算。
我们如果要引入一个数组元素,一般用下标法和指针法
下标法:就是arr[ ]形式。
指针法: *(p+i)形式。
以以下代码为总结:
三丶指针和字符串 (目前只会一级指针)
在C语言中没有字符串的数据类型,但是可以用字符数组和字符指针储存字符串。
1丶字符数组
代码附上:
其中对于%s来说,只需要告诉他首地址就可以打印出整个字符串。
2丶字符指针
这个与字符数组就是一样的结果。
所以对字符串而言,也可以不定义字符数组,直接定义指向字符串的指针变量,利用该指针变量对字符串进行操作。
3丶字符数组与字符指针的区别
1.他们的存储方式不同。
字符数组由同一类型的元素组成,每个元素存放一个字符,但是字符串存放的是字符串的首地址。
2.赋值的方式不同。
第一个赋值是正确的,第二个就是错误的。因为对于字符数组,只能对各个元素进行赋值。
3.运算的方式不同。
第一个代码可以进行++运算,但是第二个代码就不行。
因为对于字符指针来说,指针变量的值是可以改变的,如第一个代码就是输出指针指向的单元开始一直到'\0'结束。
而对于数组指针来说,字符数组名是一个常量,不能进行++和--运算。
四丶指针和函数
1.函数参数为指针
以简单的比大小为例。
通过对比发现,其实只是多加了一个*,然后参数为指针的函数引用的是函数的地址,并无多大区别。
2.指向函数的指针(函数指针)
首先函数指针是一个指针,它是指向函数的指针,它的定义式:数据类型 (*指针变量名)()
3.返回指针值的函数(指针函数)
同理指针函数是一个函数,它的返回值为指针,它的定义式:数据类型 *函数名()