指针类型
(注意是在32位下!!!)
指针也是有类型的,但是每个类型占用的空间大小一样32位操作系统是4个字节,64位下就是8个字节
#include <stdio.h>
int main()
{
printf("%d ", sizeof(char*));
printf("%d ", sizeof(short*));
printf("%d ", sizeof(int*));
printf("%d ", sizeof(long*));
printf("%d ", sizeof(long long*));
printf("%d ", sizeof(float*));
printf("%d ", sizeof(double*));
return 0;
}
指针加减
加法:
(注意是在32位下!!!)
指针相加也是不一样的比如int类型+1加的就是4个字节,char类型相加就是1个字节。
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr;
printf("%p\n", p);
p++;
printf("%p\n", p);
return 0;
}
这里显示的是十六进制(满16进1然后这一位变成0)的数字,c对应的就是十进制的12(12+4=16然后进1变成0)可以看到int*+1类型是4个字节。
十六进制表
减法:
//数组名等于首元素地址
//&arr[0] = arr
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
int* pc = arr;
for (int i = 0; i < sz; i++)
{
p++;
}
printf("%d", p - pc);
return 0;
}
可以看到指针相减得到的是元素的个数(前提是指针指向的是同一块内存)
const修饰指针
int main()
{
int a = 10;
const int* p = &a;
//这里限制的是*p就是不能修改a的值
int* const p1 = &a;
//这里限制的是p1不能修改p1的地址
return 0;
}
野指针
int main()
{
int* p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
int main()
{
int arr[10] = {0};
int *p = &arr[0];
int i = 0;
for(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();//这也是野指针,因为函数返回时空间就会收回这时候p指针还在存放地址就很危险
printf("%d\n", *p);
return 0;
}
//怎么规避野指针能下面所示
int main()
{
int num = 10;
int*p1 = #
int*p2 = NULL;
//不用的时候直接赋给它一个空指针,NULL其实就是0,但是如果写0是不对的因为编译器不理解你写的是整数0还是指针0
//还有我们使用前可以这样做
int main()
{
int num = 10;
int*p1 = #
int*p2 = NULL;
if (p1 != NULL)
//使用
return 0;
}