动态数组与字符串常量可算是两种“另类”数组。
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;
}
这个程序不使用任何数组形式的引用,不使用循环,就可以打印出用*号组合出来的菱形。当然,笔者并非鼓励大家编写这样的代码,但通过这样的例子加深对字符串常量的认识,仍然是非常重要的。
发表评论
-
《再再论指针》后记
2011-03-02 11:25 650在这篇后记中,笔者将对三个问题进行补充: 一、 ... -
再再论指针----篇首语
2011-03-02 11:24 563指针是C语言规范 ... -
第十章 围绕p()与(*p)()的争论
2011-03-02 11:23 686对于一个函数: void func(void) ... -
第九章 指针与const
2011-03-02 11:22 664const一词是英文constan ... -
第八章 右左法则----复杂指针解析
2011-03-02 11:22 641上一章费那么多唇舌讨论C语言的声明,其实目的都是为了这一 ... -
第七章 C语言声明详解
2011-03-02 11:21 675人们常说,C语言的 ... -
第五章 指向数组的指针
2011-03-02 11:19 1069讲到第五章了,数组两个字还离不开我们的左右,数组的内容 ... -
第四章 [ ]运算符的本质
2011-03-02 11:18 725数组是存在于人们头 ... -
第三章 数组的解剖学
2011-03-02 11:17 585这一章我们来讨论 ... -
第二章 再一次吃惊----数组的数组与多维数组的区别
2011-03-02 11:17 494看见这个题目,也许有些人就会嘀咕了:难道两者不是一样的 ... -
第一章 什么是数组名?----一个让你吃惊的事实!
2011-03-02 11:15 708数组是指针的基础,多数人就是从数组的学习开始指针的旅程的 ... -
图书推荐
2011-02-19 19:04 793图书收藏夹 ...
相关推荐
JavaScript 另类遍历数组实现代码,大家可以看下。
这是一个非常简单的小程序,利用vc++做成的,输入数组的大小,然后输入数组的数据,再输入你要求的K的值,就可以求出你想要的值了!
今天小编就为大家分享一篇关于C语言结构体数组同时赋值的另类用法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
财务管理第9章另类投资及其市场.pptx
javascript中的数组 数组的创建 直接创建方式 var ... 二维数组(多维)创建方式:var a = new Array([1,2,3], [4,5,6], [7,8,9]); var b = [[1,2,3], [4,5,6], [7,8,9]]; 创建数组注意
第6章 数组 6.1 一维数组 6.2 多维数组 6.3 字符串数组 第7章 面向对象和类的概念 7.1 面向对象程序设计基本概念 7.2 类 7.3 成员变量 7.4 方法 7.5 构造函数 第8章 类的继承性和多态性 8.1 类...
另类效果
MC另类套词 五项MC另类套词 五项MC另类套词 五项MC另类套词 五项MC另类套词 五项MC另类套词 五项MC另类套词 五项
另类仙剑
另类导航菜单.rar另类导航菜单.rar另类导航菜单.rar另类导航菜单.rar另类导航菜单.rar另类导航菜单.rar
另类效果
黑色另类的个人博客模板_黑色 另类 个人 博客 个性
气势另类效果.喜欢的朋友可以下载试试
KX另类效果
云计算和物联网是当前IT领域两个热点话题。云计算和物联网的定义是什么
另类网页特效集锦另类网页特效集锦另类网页特效集锦另类网页特效集锦
js 特效 html 特效 另类导航菜单 js 特效 html 特效 另类导航菜单