- 指针是什么
- 指针与指针类型
- 野指针
- 指针运算
- 指针与函数
- 二级指针
- 指针数组
1指针是什么
指针是内存中最小单元的一个编号,也就是地址
口语中的指针是指针变量,用来存放内存地址的变量
一个小的单元是一个字节
对应32位机器,假设有32跟地址线,每根地址线在寻址时产生高低电平(0或1),产生地址为2的32次方 :2^32/1024kb==2^32/1024/1024mb/2^32/1024/1024/1024==4GB
地址是唯一标识一块内存地址的,指针在32位机器上是4字节,在64位机器上是8字节
指针变量是4个字节,可以指向内存大小取决于类型
2指针类型
2.1意义是决定指针解引用时可以访问几个字节
int a = 0x11223344;
int* pa = &a;
int* pb = &a;
printf("%p", *pa);
printf("%p", *pb);
//可以访问的地址不一样所以+1后地址不一样
printf("%p", *pa+1);
printf("%p", *pb+1);
2.2指针类型决定指针+1/-1时可以跳过几个字节(决定指针的步长)
3野指针
指针指向的位置是不可知的,
造成原因是
1指针未初始化
2指针越界访问
3指针指向的空间释放
如何减少
1初始化
2避免越界访问
3指针指向空间释放及时置空
4避免返回局部变量的地址
5使用前检查他的有效性
4指针运算
4.1指针+-整数
* vp++ = 0;
先*vp
再vp++
(* vp)++ = 0;
这种是对解引用的对象++
//给数组每个元素赋值1
int main()
{
int arr[10] = { 0 };
int i = 0;
int sz = sizeof arr / sizeof(arr[0]);
int* p = arr;
for (i = 0; i < sz; i++)
{
*p = 1;
p++;
}
等价与
int arr[10] = { 0 };
int i = 0;
int sz = sizeof arr / sizeof arr[0];
for (i = 0; i < sz; i++)
{
arr[i] = 1;
}
4.2指针-指针
指针-指针得到的是指针之间的元素的个数,,指向同一块空间的两个指针才能相减
int arr[10] = { 0 };
printf("%d\n", &arr[9] - &arr[0]);//9
应用
结合之前学习三种方式写的my_strlen
1
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
2递归方法
int my_strlen(char* str)
{
if (*str != '\0')
{
return 1 + my_strlen(str + 1);
}
else
return 0;
}
3指针-指针
int my_strlen(char* p)
{
char* start = p;
while (*p != '\0')
{
p++;
}
return (p - start);
}
4.3指针的关系运算
标准
允许指向数组元素的指针与指向 数组最后一个元素后面内存的指针进行比较,但不允许与指向数组指向第一个元素的位置的内存进行比较
5指针与数组
数组是一组相同类型的元素集合
指针就是地址
指针变量是一个变量存放的是地址
因为数组名是是数组首元素的地址由此建立联系(有两种例外)
int arr[10] = { 0 };
int i = 0;
int sz = sizeof arr / sizeof arr[0];
int* p = arr;
for (i = 0; i < sz; i++)
{
printf("%d\n", arr[i]);
printf("%d\n",*(p+i));
printf("%d\n",*(arr+i));
}
6二级指针
用来存放一级变量的地址的地址
int** ppa = &pa;//int*说明ppa指向的对象是int*,后一个*说明ppa是指针
7指针数组(好孩子)本质是数组
存放指针的数组
int a = 10;
int b = 20;
int c = 30;
int* parr[10] = { &a,&b,&c };//指针数组
与二维数组的比较
int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6, };
//1 2 3 4
//2 3 4 5
//3 4 5 6
int i = 0, j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d", arr[i][j]);
}
printf("\n");
}
int arr1[4] = { 1,2,3,4 };
int arr2[4] = { 2,3,4,5, };
int arr3[4] = { 3,4,5,6 };
int* parr[3] = { arr1,arr2,arr3 };
int i = 0, j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", (parr[i][j]));//?parr【i】拿出是arr1的地址&arr1【j】;
// printf("%d ", &arr1[1]);为什么这样不行
}
printf("\n");
}