指针
969字约3分钟
2025-05-28
指针
指针 = 内存地址
int a = 123;
int *p = &a;
printf("%d\n", a); // 123
printf("%p\n", *p); // 变量地址:000000000000007B
printf("%d\n", *p); // 123
printf("%p\n", p); // 6422036(???)
p; // 表示一个值
*p; // %d时,表示一个值,%p时,表示该值的内存地址
指针变量占用的大小,跟数据类型无关,跟编译器有关(32位:4字节;64位:8字节)
给指针变量赋值的时候,不能把一个数值赋值给指针变量
// 正确的
int a = 200;
int *p = &a;
printf("%d", *p); // 200
// 错误的
int a = 2;
int *p = 20;
函数中变量的生命周期和函数相关,函数结束了,变量也会消失
此时的函数就无法被指针调用
如果不想函数中的变量被回收,可以在变量前面加static关键字
指针数组
// 一维数组
int a[5] = {1, 2, 3, 4, 5};
int *p = a;
printf("%d", *a);
// 二维数组
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
// 定义一个指针数组
int *ptrArr[3];
// 循环将二维数组每行首地址赋给指针数组
for (int i = 0; i < 3; i++)
{
ptrArr[i] = arr[i];
}
// 定义指向指针的指针并指向指针数组
int **p = ptrArr;
printf("%d", p[1]);
书写形式 | 等价形式 | 书写形式 | 等价形式 |
---|---|---|---|
a | &a[0] | *(p + 1) + 2 | a[0 + 1] + 2 |
p | &a[0] | **p | a[0][0] |
*a | a[0] | **(p + 1) | a[0 + 1][0] |
*p | a[0] | *(*P + 2) | a[0][0 + 2] |
*(p + 1) | a[0 + 1] | *(*(p + 1) + 2) | a[0 + 1][0 + 2] |
*p + 2 | a[0 + 2] | *(p[1] + 2) | a[1][0 + 2] |
a + 1 | &a[1] | p[1] | &a[1][0] |
p + 1 | &a[1] | p[1] + 2 | &a[1][2] |
细节:数组a
赋值给指针p
的值是该数组中的第一个字符
int a[] = {1, 2, 3, 4};
int len = sizeof(a) / sizeof(a[0]);
int *p = a;
int *p1 = &a[0];
printf("%d\n", p); // 6422000
printf("%d\n", p1); // 6422000
选择指针
int a[] = {1, 2, 3, 4};
int len = sizeof(a) / sizeof(a[0]);
// 将数组赋值给指针
int *p = a;
// 将数组中的第一个数赋值给指针
int *p1 = &a[0];
printf("%d\n", *p); // 1
printf("%d\n", *p1); // 1
printf("%d\n", *(p1 + 1)); // 指针向右移动一位,输出 2
二维数组
int a[3][5] = {
{1, 2, 3, 4, 5},
{11, 22, 33, 44, 55},
{111, 222, 333, 444, 555}};
int (*p)[5] = a;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d", *(*p + j));
}
printf("\n");
p++;
}
// 输出
12345
1122334455
111222333444555
int a[] = {1, 2, 3};
int b[] = {11, 22, 33, 44};
int c[] = {111, 222, 333, 444, 555};
int *d[3] = {a, b, c};
int len1 = sizeof(a) / sizeof(int);
int len2 = sizeof(b) / sizeof(int);
int len3 = sizeof(c) / sizeof(int);
int len[] = {len1, len2, len3};
int **p = d;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < len[i]; j++)
{
printf("%d", *(*p + j));
}
printf("\n");
p++;
}
// 输出
123
11223344
111222333444555
指针函数
#include <stdio.h>
int a(int a, int b);
void b();
void main()
{
// 注意函数和指针之间的关系
// int a(int a, int b);
int (*p)(int, int) = a;
// void b();
void (*p1)() = b;
int num = p(10, 20);
printf("%d\n", num); // 30
p1(); // hello
}
int a(int a, int b)
{
return a + b;
}
void b()
{
printf("hello\n");
}
指针例子
#include <stdio.h>
void swap(int *p1, int *p2);
void main()
{
int a = 10;
int b = 20;
printf("前:%d, %d\n", a, b);
swap(&a, &b);
printf("后:%d, %d\n", a, b);
}
void swap(int *p1, int *p2)
{
int num = *p1;
*p1 = *p2;
*p2 = num;
}
int a = 123;
int *p = &a;
printf("%p\n", *p); // 变量地址:000000000000007B
printf("%d\n", *p); // 123
*p = 200;
printf("%d\n", *p); // 200
printf("%d\n", a); // 200
#include <stdio.h>
void zhi(int arr[], int len, int *min, int *max);
void main()
{
int arr[] = {5, 2, 6, 0, 10, -1, 20};
int len = sizeof(arr) / sizeof(arr[0]);
int min = arr[0];
int max = arr[0];
getMinAndMax(arr, len, &min, &max);
printf("大:%d\n", max); // 20
printf("小:%d", min); // -1
}
void getMinAndMax(int arr[], int len, int *min, int *max)
{
for (int i = 1; i < len; i++)
{
if (arr[i] > *max)
{
*max = arr[i];
}
}
for (int i = 1; i < len; i++)
{
if (arr[i] < *min)
{
*min = arr[i];
}
}
}