1. 指针是什么?
指针就是地址,口语中说的指针通常指的是指针变量。
指针变量
我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个 变量就是指针变量
#include<stdio.h>
int main()
{
int a=10;
int* p=&a;//指针变量 32位4个字节 64位8个字节 不管字符类型
return 0;
}
指针的大小在32位平台是4个字节,在64位平台是8个字节。
2.指针和指针类型
int num = 10;
p = #
char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
(1)指针加减整数
#include<stdio.h>
int main()
{
int a=0x11223344;
int* pa=&a;
char* pc=&a;
printf("%p\n",pa);
printf("%p\n",pa+1);//加字节数 跳4个字节
printf("%p\n",pc);
printf("%p\n",pc+1);//跳1个字节
return 0;
}
总结:指针的类型决定了指针向前或者向后走一步有多大(距离)。
(2)指针的解引用
p是指针变量 *p可以访问相应地址对应的变量值
#include<stdio.h>
int main()
{
int arr[10]={0};
//int* p=arr;//数组名 首元素的地址
char*p=arr;//一个字节一个字节跳 跳10个字节 等于跳2个半
int i=0;
for(i=0;i<10;i++)
{
*(p+i)=1;
}
return 0;
}
char跳10个字节等于int跳2.5个字节
所以整个数组变为1 1 0 0 0 0 0 0 0 0
3.野指针
(1)指针未初始化
int *p;//局部变量指针未初始化,默认为随机值
(2)指针越界访问
#include<stdio.h>
int main()
{
int arr[10]={0};
int *p=arr;
int i=0;
for(i=0;i<12;i++)
{
p++;
}
//越出数组所有元素后 会越界访问 变为野指针
}
(3)如何规避野指针
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性
4.指针运算
指针-指针
int main()
{
char ch[5]={0};
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",&arr[9]-&ch[0]);//这样写 未知 指针变量不同
printf("%d\n",&arr[0]-&arr[9]);//指针减去指针等于中间元素个数
}
my_strlen(char* str)
{
char* start=str;
char* end=str;
while(*end!='\0')
{
end++;
}
return end-start;
}
不同类型的指针相减为随机值
相同类型的指针相减为中间元素或者字符个数
5.指针和数组
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}
两个结果一样
数组名表示的是数组首元素的地址。(2种情况除外)
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; i++)
{
printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i);
}
return 0;
}
两边结果一样
等效:&arr[i]=p+i
所以*(p+i)=arr[i]
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i<sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
遍历整个数组
6. 二级指针
int a=10;
int *pa=&a;
int **ppa=&pa;
a的地址存放在pa中
pa的地址存放在ppa中
pa是一级指针
ppa是二级指针
int b = 20; *ppa = &b;
//等价于 pa = &b;
*ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
**ppa = 30;
//等价于*pa = 30; //等价于a = 30;
7. 指针数组
指针数组不是指针 是数组 是存放指针的数组
int* arr3[5];、
arr3是一个数组,有五个元素,每个元素是一个整形指针。
#7指针初阶#完