目录
什么是指针?
不同类型指针,访问权限不同
例
指针类型和数据类型不能需保持统一
指针和数组
模拟strlen方法求字符串长度
移位指针实现
指针 - 指针实现
&arr[i] == p + i
arr传参 arr[i] == *(arr+i);
二级指针
what?
指针数组
二级指针创建二维数组
1. 指针是内存中一个最小单元的编号,也就是地址2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量3. 本质上指针就是地址,口语中说的指针,其实就是指针变量,指针变量就是用来存放指针地址的4. 我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个 变量就是指针变量5. 指针变量存储指针时(如0x11223344)在32位是4个字节,64位字节是8位字节
指针变量的大小和指针类型没有关系,如下
char *pc = NULL;
int *pi = NULL;
double *pd = NULL;
short *ps = NULL;
printf("%d\n", sizeof(char *)); // 8
printf("%d\n", sizeof(pc)); // 8
printf("%d\n", sizeof(pi)); // 8
printf("%d\n", sizeof(pd)); // 8
printf("%d\n", sizeof(ps)); // 8
如下,在这段代码中,int A = 0x11223344; 定义了一个整数变量 A,其初始值为十六进制数 0x11223344。然后,char *PC = (char *)&A; 创建了一个指针 PC,指向变量 A 的地址。通过类型转换 (char *)&A,将整数指针转换为字符指针。接下来,*PC = 0; 对指针 PC 解引用并将其指向的内存位置赋值为 0。因为 PC 是字符指针,所以这个操作将字符型的 0 赋值给了 A 的最低字节,即将 0x11223344 修改为 0x11223300。
int A = 0x11223344; // 16进制
// int *PA = &A;
// *PA = 0; // 0
char *PC = (char *)&A;
*PC = 0; // 0x11223300
int b = 0x11223344;
int *Pb = &b;
char *Pch = (char *)&b;
printf("Pb = %p\n", Pb); // 000000a178fffd24
printf("Pch = %p\n", Pch); // 000000a178fffd24
/*
*指针的类型决定了指针 +-1 操作的时候,跳过几个字节,决定了指针的步长, 例如double类型 + 1,跳过8个字节访问
也就是不同类型的指针类型,所访问的权限不同
*/
printf("Pb = %p\n", Pb + 1); // 000000a178fffd28 跳过4个字节
printf("Pch = %p\n", Pch + 1); // 000000a178fffd25 跳过1个字节
指针变量存放的是地址,他映射到变量的内存地址,然而指针变量根本不知道变量的类型,所以需要在指针变量中定义类型来决定变量的移动步进
如下 int* 和 float* 不能通用
int d = 0;
int *pi = &d; // 解引用访问4个字节,pi+1也是跳过4个字节
float *pn = &d; // 解引用访问4个字节,pf+1也是跳过4个字节
// *pi = 100;
*pn = 100.0; // 会有意向不到的结果,因为整形和浮点型在内存中存放的方式是不同的
int arr[10] = {0};
printf("%d\n", &arr[9] - &arr[0]); // 9, 就是指针之间的元素个数
int my_strlen1(char *str) // 传过来的实际是 a 字符的地址
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int len = my_strlen1("abcdef");
printf("%d\n", len); // 6
int my_strlen2(char *str)
{
char *startStr = str;
while (*str != '\0')
{
str++; // 最后一次执行后,str指针变量指向了 \0
}
return (str - startStr);
}
int len = my_strlen2("abcdef");
printf("%d\n", len); // 6
int arr[10] = {0};
int *p = arr; // arr首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
printf("%p----%p\n", &arr[i], p + i); // 通过指针访问数组元素 (此处两个值一模一样)
}
int test(int arr[], int sz) // arr是arr首元素地址
{
for (int i = 0; i < sz; i++)
{
printf("%d", arr[i]); // arr[i] == *(arr+i);
}
}
int ary[10] = {0};
test(ary, 10);
二级指针变量,存放的是一级指针变量的地址
如下:
pa是一级指针变量,*代表后面是指针变量,int代表指针变量所指向的地址是int类型的数据,ppa是二级指针变量,存放一级指针变量pa的指针地址(指针变量为4个字节或8字节)
int a = 10;
int *pa = &a;
int **ppa = &pa;
**ppa = 20;
printf("%d\n", a); // 20
——>存放指针的数组就是指针数组
int b = 10;
int c = 20;
int d = 30;
int *parr[10] = {&b, &c, &d}; // parr就是存放指针的数组
for (int i = 0; i < 3; i++)
{
printf("%d\n", *(parr[i])); // 10 20 30
}
int arr1[4] = {1, 2, 3, 4};
int arr2[4] = {2, 3, 4, 5};
int arr3[4] = {3, 4, 5, 6};
int *parrCreate[3] = {arr1, arr2, arr3};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
/*
1 2 3 4
2 3 4 5
3 4 5 6
*/
printf("%d ", parrCreate[i][j]);
}
printf("\n");
}