|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 moc 于 2018-8-18 13:00 编辑
1、一维数组和二维数组
int a1[5],内存会分配连续的5*4个字节的内存空间,并把首元素地址(及类型)给a1,(所以a是一个指针,未退化的数组指针)同时&a为该整个数组的地址,其值和a一样,但它是数组数据类型指针,步长为整个数组的大小;
对于二维数组 int a2[3][5],内存会分配连续的3*5*4个字节的内存空间,其中a2为数组首地址,它是一个二级常量指针,且是一个指向数组类型指针,其步长是数组一行的大小。
总结:
int a[5] 一维数组名代表数组首元素的地址,==> a 的类型为 int *
int b[2][5] 二维数组名同样代表数组首元素的地址,== > b的类型为 int (*)[5] 数组类型的指针,也即数组指针
数组指针的存在是为了解决线性空间存储下的步长问题。
- void main()
- {
- // 一维数组
- int i = 0, j = 0;
- int a1[5] = { 3, 4, 5, 12, 2 };
- //直接定义一个数组指针
- int(*p)[5] = &a1; // &a的步长 5*4 = 20
- for (i = 0; i < 5; i++)
- {
- //printf("%d\n", (*p)[i]);
- }
- // 二维数组
- int a2[3][5];
- // a2 --> 数组首元素的地址 --> 一个常量指针 --> 是一个数组指针
- p = a2;
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 5; j++)
- {
- p[i][j] = i + j;
- printf("%d\n", p[i][j]);
- }
- }
- // &a1 和 a2是一样的类型,为了解决步长问题,数组类型的指针+1跳一行数组的大小;数组类型的指针即数组指针
- printf("一维数组&a1: %d &a1+1 : %d \n", &a1, &a1+1);
- printf("二维数组 a2: %d a2+1 : %d \n", a2, a2 + 1);
- system("pause");
- }
复制代码
2、二维数组存储方式
不管数组是几维数组,都是线性存储的,数组指针就是为解决步长问题提出来的,数组指针每次跳一行的空间;
下面我们把数组类型的指针(二级)强制转化为一级指针,来测试二维数组是线性存储的。
- int printf2Array(int *p, int num)
- {
- int i = 0;
- for (i = 0; i < num; i++)
- {
- printf("%d ", p[i]);
- }
- }
- void main()
- {
- int i, j, tmp = 0;
- int a2[3][5];
- int *p = NULL;
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 5; j++)
- {
- a2[i][j] = tmp++;
- //第i行第j列赋值
- //*(*(a2 + i) + j) 就相当于 tmp++;
- }
- }
- p = (int *)a2; // 数组指针强制转化为一级指针
- printf2Array(p, 15); //用转化后的一级指针打印数组
- system("pause");
- }
复制代码
3、数组做函数参数
1、c语言只是只是以机械的值的拷贝方式来传递参数(实参-->形参)
- int fun(int a[5], int b_t)
- {
- printf("%d\n%d\n", b_t ,sizeof(a));
- }
复制代码
原因1:高效
原因2:C语言在处理a[n]的时候,他只知道&a[0]是多少,没有办法知道n可以为多少,只能把&a[0]传给形参。
虽然在形参中 int a[5], 函数可以得到5这个数字,但 C 并没有这么做,所以写和没写是一样的。
2、数组做函数参数退化问题
一维数组做函数参数推演:
- int printf1Array(char buf[64]);
- int printf1Array(char buf[]);
- int printf1Array(char *buf);
复制代码
二维数组做函数参数推演:
- int printf2Array(char buf[10][30]);
- int printf2Array(char buf[][30]);
- int printf2Array(char (*buf)[30]);
复制代码
示例程序:
- #include "stdlib.h"
- #include "stdio.h"
- #include "string.h"
- // 把(*ArrayStr)[30]换成ArrayStr[10][30]或ArrayStr[][30]是同样的意思,形参时都是数组指针
- int printfArray(char (*ArrayStr)[30], int iNum)
- {
- int i;
- for (i = 0; i < iNum; i++)
- {
- printf("%s \n", ArrayStr[i]);
- }
- return 0;
- }
- int sortArrayStr(char myArray[10][30], int iNum)
- {
- int i = 0, j = 0;
- char buf[30];
- for (i = 0; i < iNum; i++)
- {
- for (j = i + 1; j<iNum; j++)
- {
- if (strcmp(myArray[i], myArray[j]) > 0)
- {
- strcpy(buf, myArray[i]);
- strcpy(myArray[i], myArray[j]);
- strcpy(myArray[j], buf);
- }
- }
- }
- return 0;
- }
- int main()
- {
- int i = 0, j = 0;
- char buf[30]; //buf数组名代表数组元素首地址
- // 下面的char *ArrayStr[] = { "ccccc","aaaa", "bbbb", "11111"}(数组指针)内存模型不一样
- char myArray[10][30] = { "cccc", "aaaa", "dddd", "11111" };
- printf("排序之前:\n");
- printfArray(myArray, 4);
- sortArrayStr(myArray, 4);
- printf("排序之后:\n");
- printfArray(myArray, 4);
- system("pause");
- return 0;
- }
复制代码
4、等价关系
数组参数 等效指针参数
一维数组char a[10] 指针 char*
指针数组 char *a[10] 指针的指针 char **a
二维数组 char a[10][30] 数组的指针 char(*a)[30]
|
|