指针:是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。
1.由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。
2.指针就是变量,用来存放地址的变量
3.指针的大小在32位平台是4个字节,在64位平台是8个字节。
int main()
{
int a = 10; //a占四个字节
int * pa = &a; //pa拿到的是a的四个字节中第一个字节的地址
//将a的地址存放在pa变量中,pa就是一个之指针变量。
*pa = 20;
return 0;
}
一、指针和指针类型
int main()
{
int* pa;
char* pc;
float* pf;
printf("%d\n", sizeof(pa));
printf("%d\n", sizeof(pc));
printf("%d\n", sizeof(pf));
return 0;
}
二、指针类型的意义
1.指针类型决定了:指针解引用的权限有多大
2.指针类型决定了:指针走一步,能走多远(步长)
int main()
{
//int a = 0x11223344;
//int* pa = &a;
//*pa = 0;
int arr[10] = { 0 };
int *p = arr;
char *pc = arr;
printf("%d\n", p);
printf("%d\n", p+1);
printf("%d\n", pc);
printf("%d\n", pc+1);
return 0;
}
int main()
{
int arr[10] = { 0 };
int *p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i)=1; //p+i:其实是下标为i的地址
}
return 0;
}
三、野指针:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
情况1:指针未初始化
int main()
{
//这里的p,就为野指针
int* p; //p是一个局部的指针变量,局部变量不初始化的话,默认为随机值
*p = 20; //非法访问内存
return 0;
}
情况2:指针越界访问
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i <= 10; i++)
{
*p = i; //当指针指向的范围超出数组arr的范围时,p就是野指针
p++;
}
return 0;
}
情况3:指针指向的空间释放
int* test()
{
int a = 10;
return &a;
}
int main()
{
int *p = test();
*p = 10;
return 0;
}
四、如何避免野指针:
1、指针初始化
int main()
{
//当前不知道p应该初始化为什么地址的时候,直接初始化为NULL(空指针)
int* p = NULL;
//明确指针初始化的值
int a = 10;
int* ptr = &a;
return 0;
}
2、小心指针越界
int main()
{
//c语言本身是不会检查数据的越界行为的,因此需要自己检查
return 0;
}
3、指针指向空间释放即使置NULL
4、指针使用之前检查有效性
五、指针运算
1.指针 +- 整数
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* p = arr;
int* pend = arr + 9;
while (p <= pend)
{
printf("%d\n", *p);
p++;
}
return 0;
}
2.指针 - 指针
//strlen的三种实现方法
//(1)计数器的方法
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
//(2)递归的方法
//
//(3)指针减去指针的方法
int my_strlen(char* str)
{
char* start = str;
while (*str != '\0')
{
str++;
}
return str - start;
}
int main()
{
int len = my_strlen("abc");
printf("%d\n", len);
return 0;
}
3.指针的关系运算
六、二阶指针
int main()
{
//a的地址存放在pa中,pa的地址存放在ppa中
//pa是一级指针,而ppa是二级指针。
int a = 10;
int* pa = &a; //pa是指针变量,一级指针
//ppa就是一个二级指针变量
int* *ppa = &pa; //pa也是一个变量,&pa取出pa在内存中的起始地址
ppa就是一个三级指针变量
//int** *pppa = &ppa;
return 0;
}
七、指针数组 - 存放指针的数组
int main()
{
int arr[10]; //整型数组 - 存放整形的数组就是整型数组
char ch[5]; //字符数组 - 存放的是字符
int* parr[5]; //整形指针的数组
}