最近闲来没事看了看c语言的数组和指针的知识,发现了很多还需要恶补的知识点,特别是在数组的时候,发现之前的理解好像和现在有了很大的不同,下面这个案例是通过“另类”数组来实现的。
#include <stdio.h>
int iLine=1;
int main(void)
{
printf("%*s\n", 7-(iLine>4?iLine-4:4-iLine), "*******"+2*(iLine>4?iLine-4:4-iLine));
if(++iLine != 8) main();
return 0;
}
代码简单吧!简单三行代码实现了一个菱形。
效果如下:
*
***
*****
*******
*****
***
*
为什么回呈现这样的结果,这里面主要使用了两个知识点:
1、字符指针常量。
2、递归调用。
动态数组的创建:
什么是动态数组:
VLA可变长数组并不为C89所支持,C99才开始支持VLA。但如果想在只支持C89的编译环境中使用VLA的话,怎么办呢?我们可以用动态数组来“模拟”,动态数组在矩阵的运算中很常见,常用来向函数传递一个大小可变的矩阵。动态数组的原理,是利用一块或多块动态分配的内存存储各维的首地址,这样就可以p[i][j]的形式访问数组的数据了。但是,动态数组并非真正的数组,它只是对数组的一种模拟。由于具有数组类型的数组名是系统行为,在用户这一级没法做到,因此只能以指针的形式存放首地址,sizeof(p)和sizeof(p[i])结果都是4字节。虽然动态数组是依靠动态分配内存来建立的,但动态的意义并非来自这里,而是指大小可变。笔者觉得用“动态数组”这个名称来命名非常适合,既不失大小可变的特征,又可以跟VLA可变长数组区分开来。
二维动态数组的创建:
#include <stdio.h>
#include <stdlib.h>
void computedata(int *, int, int);
int main(void)
{
int iData[100], x, y;
do
{
printf("The product obtained by multiplying x and y must be less than 100!");
printf("x=");
scanf("%d", &x);
printf("y=");
scanf("%d", &y);
}
while(x*y > 100);
computedata(iData, x, y);
return 0;
}
void computedata(int *ipSource, int iRow, int iColumn)
{
int **ipTemp, i, j;
ipTemp = (int **)malloc(iRow*sizeof(int*));
for(i=0; i<iRow; ++i) ipTemp[i] = ipSource+i*iColumn;
for(i=0; i<iRow; ++i) for(j=0; j<iColumn; ++j) ipTemp[i][j] += 1;
free(ipTemp);
return;
}
以上示例把动态数组ipTemp的元素都加了1,由于只是示例,笔者省略了检测数据合法性的代码。iRow是第一维上界,iColumn是第二维上界,iData是源数据缓冲区,iRow*iColumn的积不能超过iData缓冲区的大小,否则就会越界了,但可以比它小。示例中iData被定义为一维数组,当然根据自己的需要也可以用其它类型的缓冲区代替,例如动态分配的一块内存,或者多维数组,如果是多维数组,例如三维数组int iData[10][10][10],调用computedata函数时,实参iData得做一些转换:
computedata((int *)iData, x, y);或者computedata(&iData[0][0][0], x, y);都可以。
ipSource指针用来传递缓冲区的首地址,这个指针由于要用来计算各维的地址,因此最好定义为一级指针,这样比较方便。ipTemp是一个二级指针,这是因为它指向的那块内存存放的是指针,这些指针指向各维的首地址,对ipTemp的元素来说,ipTemp就是二级的。最后记得free(ipTemp);
三维动态数组的创建:
void computedata(int *ipSource, int iHigh, int iRow, int iColumn)
{
int ***ipTemp, i, j, k;
ipTemp = (int ***)malloc(iHigh*sizeof(int**));
for(i=0; i<iHigh; ++i) ipTemp[i] = (int **)malloc(iRow*sizeof(int*));
for(i=0; i<iHigh; ++i) for(j=0; j<iRow; ++j) ipTemp[i][j] = ipSource+i*iRow*iColumn+j*iColumn;
for(i=0; i<iHigh; ++i) for(j=0; j<iRow; ++j) for(k=0; k<iColumn; ++k) ipTemp[i][j][k] += 1;
for(i=0; i<iHigh; ++i) free(ipTemp[i]);
free(ipTemp);
return;
}