目录
一.指针
1.指针
指针是内存中一个最小单元的编号,也就是存放数据的地方的编号,简单的来说指针就是地址。
我们常说的指针是指针变量,指针变量是存放地址的变量。
内存单元编号:
32位机有2的32次方个内存单元 每个单元编号都是一个32位的二进制数
64位机有2的64次方个内存单元 每个单元编号都是一个64位的二进制数
不论32位机器还是64位机器,每个内存单元的空间大小是1个字节(8比特位),也就是说一个整型变量要占4个字节(变量在内存中以补码的形式存放,因此需要占4个字节)
2.1指针变量
通过&(取地址操作符,单目操作符)取出变量的内存起始地址,把起始地址存放到一个变量中,那么这个变量就是指针变量。
#include <stdio.h>
int main()
{
int a = 10; //定义整型变量时,会在内存中开辟出4个字节大小的空间(4个内存单元)
int *p = &a; //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,
//p就是一个之指针变量。
// * 说明p是指针变量
// int 说明p中存放的是int型变量的地址
return 0;
}
注意:指针变量的大小在32位平台是4个字节,在64位平台是8个字节,与什么类型的指针变量无关。因为指针变量中存放的是地址,而地址的大小只与32位和64位平台有关。
2.2指针变量的类型
变量有着不同的类型,指针变量也有类型。
char *p = NULL;
int *p = NULL;
short *p = NULL;
指针的定义方式为 类型 + * +指针变量名
char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。
2.3指针变量分类的意义:
①指针变量的类型不同,在解引用时的访问权限也各不相同
char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
总结:指针变量的类型决定了,对指针解引用的时候有多大的权限,能操作几个字节。
②指针加减整数
char型指针+1则地址1,int型指针+1则地址4。
总结:指针的类型决定了指针向前或者向后走一步有多大距离
二.野指针
概念:野指针就是指针变量指向的位置是不可知的(随机的、不正确的、没有明确限制的)
1.野指针的形成原因
①. 指针(变量)未初始化
#include <stdio.h>
int main()
{
int *p;//指针变量未初始化,默认为随机值
*p = 20; //该程序会报错,因为该指针变量是野指针,没有明确的指向
return 0;
}
②. 指针越界访问
③.指针指向的空间释放
#include <stdio.h>
int* test()
{
int a = 10;
return &a;
} //变量a出函数后会自动销毁,a变量所占的空间也会销毁。
int main()
{
int* p = test();
*p = 20; //a变量的空间释放后,不能再对a变量的地址进行解引用
return 0;
}
2.如何避免野指针
①. 指针初始化
②. 小心指针越界
③. 指针指向空间释放,及时置NULL
④. 避免返回局部变量的地址
⑤. 指针使用之前检查有效性
#include <stdio.h>
int main()
{
int *p = NULL;
int a = 10;
p = &a;
if(p != NULL)
{
*p = 20;
}
return 0;
}
三. 指针的运算
1.指针+-整数
#include <stdio.h>
int main()
{
char ch[6];
for (char* p = ch; p < &ch[6];) //for语句的调整部分可省略
//指针的的关系运算
{
*p++ = 0; //先解引用p进行赋值后再++,指针+-整数
} //数组的初始化
return 0;
}
2.指针-指针
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6, 7,8,9,10 };
char c[5];
//指针和指针相减的前提:两个指针指向同一块空间
printf("%d\n", &arr[9]- & c[0]); //err 结果没有任何意义
printf("%d\n", &arr[9] - &arr[0]); //9 指针-指针得到的是两个指针之间的元素个数
return 0;
}
注意:1.指针和指针相减的前提:两个指针指向同一块空间
2.指针-指针得到的是两个指针之间的元素个数
通过学习指针-指针可以实现一个求字符串长度的函数:
#include <stdio.h>
#include<string.h>
int my_strlen(char* p)
{
char* start = p;
while (*p != '\0')
{
p++;
}
return p - start;
}
int main()
{
char ch[] = { "abc" };
printf("%d\n", strlen(ch)); //3
printf("%d\n", my_strlen(ch)); //3
return 0;
}