指针初级详解
1. 指针是什么 指针是个变量,存放内存单元的地址 2. 指针和指针类型 3. 野指针 4.指针运算 5. 指针和数组 6. 二级指针 7. 指针数组
int main()
{
int a = 10;
int* p = &a;
总结:指针是用来存放地址的,地址是唯一标示一块地址空间的
总结:指针的大小在32位平台是4个字节,在64位平台上是8个字节
return 0;
}
- 总结:指针是用来存放地址的,地址是唯一标示一块地址空间的
- 总结:指针的大小在32位平台是4个字节,在64位平台上是8个字节
指针类型的第一个意义 解引用操作
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pc = &a;
printf("%p\n", pa);
printf("%p\n", pc);
*pa = 0;
*pc = 0;
return 0;
}
总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节),比如 char* 的指针解引用就只能访问一个字节,而int*的指针的解引用就能访问4个字节
指针类型的第二个意义 指针+整数
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pb = &a;
printf("%p\n", pa);
printf("%p\n", pa + 1);
printf("%p\n", pb);
printf("%p\n", pb + 1);
指针类型决定了:指针走一步走多远(指针的步长)
int* p; p+1 -->4个字节 +1意思是加了一个整型
char* p p+1 -->1个字节 +1意思是加了一个字符型
double* p p+1 -->8个字节 +1意思是加了一个双精度型
return 0;
总结;指针的类型决定了指针向前或者向后走一步有多大(距离)
}
总结;指针的类型决定了指针向前或者向后走一步有多大(距离)
野指针
野指针:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
野指针成因 : 1. .指针未初始化 2. 指针越界访问 3. 指针指向的空间释放
1.指针未初始化
int main()
{
int *p;
return 0;
}
2.指针越界访问
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 12; i++)
{
*(p++) = i;
}
return 0;
}
3.指针指向的空间释放
int* test()
{
int a = 10;
return &a;
}
int main()
{
int *p = test();
*p = 20;
return 0;
}
这是一个指针越界访问的问题
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
printf("%d\n", *p);
return 0;
}
如何规避野指针
1. 指针初始化 2. 小心指针越界 3. 指针指向空间释放即使置为null 4. 指针使用之前检查有效性
int main()
{
int a = 10;
int *pa = &a;
*pa = 20;
pa = NULL;
if (pa != NULL)
{
}
return 0;
}
指针运算
1. 指针+整数 2. 指针-整数 3. 指针的关系运算
指针加整数
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\n", *p);
p+=2;
}
return 0;
}
指针减整数
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\n", *p);
p -= 2;
}
return 0;
}
指针是可以进行关系运算的
#define N_VALUES 5
int main()
{
float values[N_VALUES];
float *vp;
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
return 0;
}
指针减去指针 指针-指针
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", &arr[9] - &arr[0]);
return 0;
}
strlen - 求字符串长度的
递归 - 模拟实现了strlen - 计数器的方式,递归的方式
int my_strlen(char* str)
{
char* start = str;
char* end = str;
while (*end != '\0')
{
end++;
}
return end - start;
}
int main()
{
char arr[] = "bit";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
指针的关系运算 就是比大小
#define N_VALUES 5
int main()
{
float values[N_VALUES];
float *vp;
for (vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}
for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--)
{
*vp = 0;
}
return 0;
}
c语言标准规定: 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较 下图就说明了
指针和数组
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
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);
return 0;
}
通过数组打印
通过指针打印
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
printf("%d ", *(p + i));
}
return 0;
}
通过指针来访问数组
int main()
{
int arr[10] = { 0 };
int i = 0;
int* p = arr;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
printf("%d ", *(p + i));
}
总结:p+i其实计算的是数组arr下标为i的地址
: 那我们就可以直接通过指针来访问数组
return 0;
}
实例
实例
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;
}
二级指针
int main()
{
int a = 10;
int* pa = &a;
int** ppa = &pa;
**ppa = 20;
printf("%d\n", **ppa);
printf("%d\n", a);
return 0;
}
指针数组 – 数组
数组指针 – 指针
整型指针数组
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* arr2[3] = {&a,&b,&c};
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d ", *(arr2[i]));
}
return 0;
}
|