一、指针是什么
1.指针是内存中最小单元的编号,也就是地址
2.平时口语中说的指针(也就是指针变量),用来存放内存地址的变量
每个内存单元大小:1个字节
指针变量的大小
32位:4个字节
64位:8个字节
二、指针类型
int * 的指针解引用访问4个字节
char* 的指针解引用访问1个字节
结论:指针类型可以决定指针解引用的时候访问多少个字节(指针的权限)
应用:指针类型决定指针+1/-1时的步长
整型指针:跳过4个字节 sizeof(type)
字符指针:跳过1个字节 sizeof(type)
三、野指针
野指针:指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
int main()
{
int* p;//局部变量不初始化的时候,内容是随机值
*p = 20;
printf("%d\n", *p);
return 0;
}
避免野指针
1.指针初始化
明确知道指针应该初始化为谁的地址,就直接初始化
不知道指针初始化为什么值,暂时初始化为NULL
2.小心指针越界
3.指针指向的空间释放,及时置NULL
4.避免返回局部变量的地址
5.指针使用之前检查有效性
四、指针运算
指针+-整数
int main()
{
int arr[10] = { 0 };
//不使用下标操作数组
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
*p = i;
p++;//p=p+1
}
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
指针-指针
int main()
{
int arr[10] = { 0 };
printf("%d\n", &arr[9] - &arr[0]);//9
return 0;
}
指针-指针(是个数值)的绝对值:是指针和指针之间的元素个数
指针-指针的前提:两个指针指向同一块空间
int my_strlen(char* s)
{
char* start = s;
while (*s != '\0')
{
s++;
}
return s - start;
}
int main()
{
char arr[] = "abcdef";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
指针的关系运算
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
五、指针和数组
数组:一块连续的空间,可以存放1个或多个类型相同的数据
指针:用来存放地址,大小是4/8个字节
数组与指针的联系
数组中,数组名其实是数组首元素的地址,数组名==地址==指针
数组可以通过指针来访问
当我们知道数组首元素的地址的时候,因为数组是连续存放的,所以通过指针就可以遍历访问数组
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int* p = arr;
for (i = 0; i < 10; i++)
{
printf("%p==%p\n", p+i,&arr[i]);
}
return 0;
}
输出结果
例子
//指针数组(char)
int main()
{
char arr1[] = "abcdef";
char arr2[] = "hello world";
char arr3[] = "cuihua";
//指针数组
char* parr[] = { arr1,arr2,arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%s\n", parr[i]);
}
return 0;
}
输出结果:abcdef
hello world
cuihua
//指针数组(int)
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
//指针数组
int* parr[] = { arr1,arr2,arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
输出结果: 1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
六、二级指针
首先说明什么是一级指针,代码如下
int main()
{
int a = 10;
int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的,是变量就有地址
return 0;
}
通过调试中的监视窗口,我们可以看到指针变量p取到了a的地址,(是变量就会有地址),因此,指针变量p也会有地址,即指针变量p(一级指针int*)的地址就是&p(二级变量int**)