概述
文章目录
- 一、指针是什么
- 二、指针和指针变量
- 1.左值与右值
- 2.两者的区别
- 三、指针和指针类型
- 1.定义指针
- 2.大小端
- 3.指针的解引用
- 四、野指针
- 野指针成因
- 如何规避野指针
- 五、指针运算
- 1.指针+- 整数
- 2.指针-指针
- 3.指针的关系运算
- 六、指针和数组
- 七、二级指针
- 八、指针数组和数组指针
- 1.指针数组
- 2.数组指针
一、指针是什么
指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。
总结:
- 指针就是地址,地址就是指针。
- 使用指针的目的是提高使用效率
- 指针是用来存放地址的,地址是唯一标示一块地址空间的。
- 指针的大小在32位平台是4个字节,在64位平台是8个字节。
二、指针和指针变量
1.左值与右值
空间 对应 左值
例:(对a来说)
a = 20; //当把值赋给a时,是给a的空间写入20。
内容 对应 右值
例:(对a来说)
b = a; //把a的内容赋给b。
2.两者的区别
指针
指针就是地址,地址就是指针。
指针变量
指针变量是变量。定义一个指针变量,是在内存中开辟一个空间,该空间里面存放地址。
如何使用
指针更多强调的是内容(对应右值),指针变量更多强调的是空间(对应左值)。判断一个指针和一个指针变量要通过判断它是左值还是右值。
int *p = &a; //定义了指针变量p
p = &b; //将b的地址放在p的空间
int *q = p; //定义了指针变量q,把p的内容(地址)给了q(空间)
大部分使用的都是指针变量,但是书中经常简称定义一个指针,这种说法并没有错,这时通过上下文,通过左值和右值进行判断。
指针和指针变量不一样,严格来说,定义一个指针是个错误的说法。但是,在日常生活中,还是将指针和指针变量混在一起使用,因为大部分人和书将指针和指针变量混在一起。既可以说定义一个指针,也可以说定义一个指针变量,它到底是什么需要自己判断。
三、指针和指针类型
1.定义指针
char *pc = NULL;
short *ps = NULL;
int *pi = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
这里可以看到,指针的定义方式是:type + *
。 其实: char*
类型的指针是为了存放 char
类型变量的地址。 short*
类型的指针是为了存放short
类型变量的地址。int*
类型的指针是为了存放int
类型变量的地址。
2.大小端
为什么有大小端区别之分
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。即如何存放高低权值位在高低地址中。
小端:将低权值数据放入低地址字节中
大端:将低权值数据放入高地址字节中
3.指针的解引用
对指针对解引用代表指针所指向的目标
#include <stdio.h>
int main()
{
int n = 0x11223344;
char* pc = (char*)&n;
int* pi = &n;
*pc = 0;
*pi = 0;
return 0;
}
作图分析:
逐步分析:
第一步:
可看出此时是小端存储
第二步:
将该数的第一个字节清0了
第三步:
将该变量整个清0了
总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。 比如: char*
的指针解引用就只能访问一个字节,而 int*
的指针的解引用就能访问四个字节。
四、野指针
概念
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
野指针成因
1.指针未初始化
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0; }
2.指针访问越界
#include <stdio.h>
int main()
{
int arr[10] = {0};
int *p = arr;
int i = 0;
for(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0; }
3.指针指向的空间释放
略…
如何规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放即使置NULL
- 指针使用之前检查有效性
五、指针运算
1.指针± 整数
#include <stdio.h>
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%pn", &n);
printf("%pn", pc);
printf("%pn", pc+1);
printf("%pn", pi);
printf("%pn", pi+1);
return 0; }
输出结果:
对指针加1或 减1代表对其改变指针所指向类型的大小
2.指针-指针
两个指针相减代表指针之间所经历的元素(由参与运算的指针类型决定)个数
int my_strlen(char *s) {
char *p = s;
while(*p != '