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