指针是个变量,是存放地址的变量。
存放在指针中的值都被当作地址来处理。
指针是用来存放地址的,地址是唯一标识一块地址空间的。
指针的大小在32位平台上是4个字节,在64位平台上是8个字节
int main()
{
printf("%d\n",sizeof(char *)); //32位系统下,结果是4
printf("%d\n",sizeof(short *)); //32位系统下,结果是4
printf("%d\n",sizeof(int *)); //32位系统下,结果是4
printf("%d\n",sizeof(double *)); //32位系统下,结果是4
}
由上面的代码及运行结果能发现:指针既然是一样的大小为什么还要区分类型呢?
int a=0x11223344;
int *pa=&a; //定义指针变量pa存放变量a的地址
*pa=0; //通过解引用操作将a的值替换成0
指针在进行解引用操作时就会发现区别
1、指针类型决定了指针进行解引用操作的时候,能够访问空间的大小
int *p; //*p能够访问4个字节
char *p; //*p能够访问1个字节
double *p; //*p能够访问8个字节
2、指针类型决定了指针走一步能走多远(指针的步长)
int *p; //p+1-->4
char *p; //p+1-->1
double *p; //p+1-->8
野指针:指针指向的位置不可知
导致原因:
1、指针未初始化
int a; //局部变量不初始化,默认是随机值
int *p; //局部的指针变量
2、指针越界访问:当指针指向的范围超过数组arr的范围时,p就是野指针
int arr[10]={0};
int i=0;
for(i=0;i<=12;i++)
{
*p=i;
p++; //*p++=i;和这两行代码表示的意思一样
}
3、指针指向的空间被释放:局部变量出作用域释放,变量a已经还给系统
int* test()
{
int a=10;
return &a;
}
int main()
{
int* p=test();
*p=20;
return 0;
}
避免野指针:
1、指针初始化
int* pa=&a; //初始化
int* p=NULL; //NULL-用来初始化指针的,给指针赋值
2、小心指针越界
3、指针指向空间释放后,可将指针置成空
4、指针使用之前检查有效性
pa=NULL;
if(pa!=NULL)
{
}
指针运算:
1、指针±整数
指针+整数
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int i=0;
int sz=sizeof(arr)/sizeof(arr[0]);
int* p=arr;
for(i=0;i<5;i++)
{
printf("%d ",*p);
p+=2;
}
return 0;
}
//打印结果是1 3 5 7 9
指针-整数
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int i=0;
int sz=sizeof(arr)/sizeof(arr[0]);
int* p=&arr[9];
for(i=0;i<5;i++)
{
printf("%d ",*p);
p-=2;
}
return 0;
}
//打印结果是10 8 6 4 2
2、指针-指针:得到的是指针到指针中间元素的个数
int my_strlen(char* str)
{
char* start=str;
char* end=str;
while(*end!='\0')
{
end++;
}
end-start;
}
int main()
{
char arr[]="world";
int len=my_strlen(arr);
printf("%d\n",len);
return 0;
}
3、指针的关系运算
比较大小
for(vp=&values[N_VALUES];vp>&values[0];)
{
*--vp=0;
}
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
指针和数组
printf("%p\n,arr); //数组名表示首元素地址
printf("%p\n",&arr[0]);
int arr[10]={0};
printf("%p\n,arr); //首元素地址
printf("%p\n,arr+1); //第二个元素地址
printf("%p\n,&arr[0]); //首元素地址
printf("%p\n,&arr[0]+1); //第二个元素地址
printf("%p\n,&arr); //数组地址
printf("%p\n,&arr+1); //跳过整个数组的地址
二级指针:
int a=10;
int* pa=&a;
int** ppa=&pa;
指针数组:存放指针的数组
int a=10;
int b=20;
int c=30;
int* arr[3]={&a,&b,&c}; //指针数组
int i=0;
for(i=0;i<3;i++)
{
printf("%d ",*arr[i]);
}
return 0;
//打印结果 10 20 30