c语言 指针与数组
关键概念
1.多个不同类型的指针可以对应同一个地址;
2.(&p)则是这样一种运算,返回一个指针,该指针的值是当时声明p 时开辟的地址,指针的类型是p的类型对应的指针类型;
3.(*p)操作是这样一种运算,获取指针p的值(变量的地址)找到对应的变量的值-----返回以(p 的值作为地址)的那个空间的值。但是如果这个变量本身就是一个地址,那么(*p)获取的值也是一个指针;
数组关键知识点
a.当数组名参与数学计算时,数组名会从"T类型的数组"转换成"指向类型T的指针",此时数组名是常量指针,不可改变其值。
b.数组名在 sizeof, 下标计算[], 取址&等操作的操作数时,是作为T类型的数组而存在的
一维数组
#include<stdio.h> #include<stdlib.h> void test() { int arr[5] = { 1,2,3,4,5 }; int* p = arr; // 赋值操作,方便观察 for (int i = 0; i < 5; i++) { printf(" %d:%p ", arr[i], &arr[i]); } printf("\n"); /* 设计说明: arr+1分析 arr+1符合数组关键知识点a,arr参与数学计算时,arr的类型转变成 int* arr的步长是sizeof(int*),即4 假设arr的指针值是0x87f904,那么arr+1对应的指针值是0x87f918 */ printf("arr = %p, arr + 1 = %p\n", arr, arr + 1); /* 设计说明: &arr分析 &arr符合数组关键知识点b,arr此时的数据类型是 int k[5] &arr的数据类型是数组指针,即 int (*k)[5] &arr的步长是sizeof(int k[5]),即20 假设arr的指针值是0x87f904,那么&arr+1对应的指针值是0x87f908 */ printf("arr = %p, &arr + 1 = %p\n", arr, &arr + 1); /* 设计说明: arr[x]分析 arr[x]符合数组关键知识点b,arr此时的数据类型是 int k[5] arr[x]即取数组类型的第x个元素 arr[x] 等价于 *(arr + x) 在*(arr + x)表达式中,arr的数据类型是int * */ printf("arr[1] = %d, *(arr + x) = %d\n", arr[1], *(arr + 1)); } void main() { test(); system("pause"); }
二维数组
#include<stdio.h> #include<stdlib.h> void test() { int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf(" %d ", arr[i][j]); } printf("\n"); } /* 设计说明: arr+1分析 arr+1符合数组关键知识点a,arr参与数学计算时,arr的类型转变成 int (*m)[4],即数组指针类型 arr的步长是sizeof(int m[4]),即16 假设arr的指针值是0x87f904,那么arr+1对应的指针值是0x87f914 */ printf("arr = %p, arr + 1 = %p\n", arr, arr + 1); /* 设计说明: &arr分析 &arr符合数组关键知识点b,arr此时的数据类型是 int n[3][4],即二维数组类型 &arr的数据类型是二维数组指针,即 int (*n)[3][4] &arr的步长是sizeof(int n[3][4],),即48 假设arr的指针值是0xd7a4f6f758,那么&arr+1对应的指针值是0xd7a4f6f788 */ printf("arr = %p, &arr + 1 = %p\n", arr, &arr + 1); /* 设计说明: arr[x][y]分析 arr[x][y]符合数组关键知识点b,arr此时的数据类型是 int n[3][4],即二维数组类型 arr[x][y]即取数组类型的第x行,第y列的元素 arr[x][y] 转换逻辑详解 arr+x 此时arr的类型是 int (*m)[4],arr的步长是20 *(arr+x)的类型是int *类型 为啥*(arr+x)的类型不是一维数组类型(int m[4])呢? 因为根据数组关键知识点a,在数学计算中,数组名都会转换为指向类型T的指针 *(arr+x)本身的类型是数组类型,在此表达式中转换成int* *(*(arr+x)+y)的类型是int类型 */ printf("arr[1][2] = %d, *(*(arr+1)+2) = %d\n", arr[1][2], *(*(arr + 1) + 2)); } void main() { test(); system("pause"); }
数组做参数
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void run1(int* p) { // 指针大小是4个字节,没有疑问 printf("run1: sizeof(p)=%lld\n", sizeof(p));//结果是4 printf("run1: p[0]=%d\n", p[0]); } void run2(int p[5]) { //当数组类型变量当作函数参数的时候会转换为指向类型T的指针 // 这里p的数据类型是int* printf("run2: sizeof(p)=%lld\n", sizeof(p));//结果是4 // 发现p的步长是4,进一步验证p的数据类型是int* printf("run2: p=%p, p+1=%p\n", p, p + 1); printf("run2: p[0]=%d\n", p[0]); } void main() { int a[5] = { 1, 2, 3, 4, 5 }; run1(a); run2(a); system("pause"); }