养浩然之气,活着不是为技术,请关心身边的人.

(转)“另类”数组

上一篇 / 下一篇  2007-09-20 12:11:45 / 个人分类:linux-C

动态数组与字符串常量可算是两种“另类”数组。

        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;
}

        下面来讨论字符串常量。
        众所周知,C语言是没有字符串变量的,因而,C89规定,字符串常量就是一个字符数组。因此,尽管字符串常量的外部表现形式跟数组完全不同,但它的确是一 个真正的数组,实际上,字符串常量本身就是这个数组的首地址,并且具有数组类型,对一个字符串常量进行sizeof运算,例如sizeof ("abcdefghi"),结果是10,而不是4。字符串常量与一般数组的主要区别,是字符串常量存放在静态存储区,而一般数组(非static)则是 在栈中静态分配的。由于字符串常量是数组首地址,因此可以数组引用的形式使用它,例如:

printf("%s", &"abcdefghi"[4]);

这将打印出字符串efghi。还可以这样:

printf("%s", "abcdefghi"+4);

同样打印出字符串efghi。实际上,&"abcdefghi"[4]等价于&*("abcdefghi"+4),去掉&*后,就是"abcdefghi"+4了。

我们可以利用字符串常量这些特性写出一些有趣的程序来,例如:


#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;
}

这个程序不使用任何数组形式的引用,不使用循环,就可以打印出用*号组合出来的菱形。当然,笔者并非鼓励大家编写这样的代码,但通过这样的例子加深对字符串常量的认识,仍然是非常重要的。

trackback:http://blog.csdn.net/megaboy/archive/2005/09/17/482774.aspx


TAG: linux-C

引用 删除 Guest   /   2008-04-03 09:09:22
罐头,黄桃罐头,白桃罐头,蘑菇罐头,水果罐头
  以 罐头,黄桃罐头,白桃罐头,蘑菇罐头,水果罐头为主 江苏徐州绿洲商贸有限公司成立于2003年,坐落在航空,铁路,公路,水运都极为发达得苏鲁豫皖交界。素有五省通衢之称。产品涉及食品罐头,工艺品,家居用品、品牌化妆品、品牌运动装、机械配件几大类。崇尚奋进、诚信的原则,确信经过自己的辛勤劳动可以获得更大的发展理念。
    其中销售的昌平水果罐头是以出口欧洲为主企业的产品。产品有黄桃水果罐头、白桃水果罐头、糖水梨水果罐头、蘑菇罐头皆达到国家优质和欧盟标准。深的海内外客户的赞誉。罐头包装分易拉罐式和听装的,便于运输和保质期。
   因网站上可以上传的照片有限。请去我qq空间的相册去看吧
   结成欢迎和各界商家携手合作!

    网址    http://www.jsxzlzsmyxgs.21food.cn/     照片网络照片主页 http://xzlzsm.51.com

    我的网店   http://shop35413468.taobao.com/?pageNum=3&queryType

  联系人:刘先生       联系电话13615133227           工作qq   958469818



江苏东盛电子

网址:http://www.jslzsmyxgs.21food.cn
引用 删除 Guest   /   2008-04-02 21:17:56
暨华教育服务中心联系方式13242851818电子邮件;jheduzx@126.com公司网站;http://www.jheduzx.cn 客服QQ;504875656本中心免试入学,电子注册,上网查询,快速取证、社会认可,学制短,提供全日制学籍档案。毕业证书对求职,应聘、出国留学移民、技能考核、晋级、资格评定、升职、涨薪等都具有效力。毕业证书可在学校官方网站永久查询,有档案,有学籍,有成绩单,有完整的手续。专业齐全,可以任意选报。真实、合法、快速、便捷、学费低!是您最理想的选择!



联系方式  13242851818
电子邮件; jheduzx@126.com
公司网站; ;http://www.jheduzx.cn
客服QQ;   504875656

网络推广

网址:http://www.aaaaa.cn
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

数据统计

  • 访问量: 21762
  • 日志数: 146
  • 建立时间: 2007-08-01
  • 更新时间: 2008-02-20

RSS订阅

Open Toolbar