📄 014.htm
字号:
<BR>
<P> 2.2.2 指向一个由n个元素所组成的数组指针
<BR> 在Turbo C中, 可定义如下的指针变量:
<BR> int (*p)[3];
<BR> 指针p为指向一个由3个元素所组成的整型数组指针。在定义中,
圆括号是不
<BR>能少的, 否则它是指针数组, 这将在后面介绍。这种数组的指针不同于前面介绍
<BR>的整型指针, 当整型指针指向一个整型数组的元素时, 进行指针(地址)加1运算,
<BR>表示指向数组的下一个元素, 此时地址值增加了2(因为放大因子为2), 而如上所
<BR>定义的指向一个由3个元素组成的数组指针, 进行地址加1运算时, 其地址值增加
<BR>了6(放大因子为2x3=6), 这种数组指针在Turbo C中用得较少, 但在处理二维数
<BR>组时, 还是很方便的。例如:
<BR> int a[3][4],
(*p)[4];
<BR> p=a;
<BR> 开始时p指向二维数组第0行, 当进行p+1运算时, 根据地址运算规则,
此时
<BR>放大因子为4x2=8, 所以此时正好指向二维数组的第1行。和二维数组元素地址计
<BR>算的规则一样, *p+1指向a[0][1], *(p+i)+j则指向数组元素a[i][j]。
<BR> 例1
<BR> int a[3] [4]={
<BR> {1,3,5,7},
<BR> {9,11,13,15},
<BR> {17,19,21,23}
<BR> };
<BR> main()
<BR> {
<BR> int i,(*b)[4];
<BR> b=a+1;
/* b指向二维数组的第1行, 此时*b[0]或
<BR>
**b是a[1][0] */
<BR> for(i=1;i<=4;b=b[0]+2,i++)/*
修改b的指向, 每次增加2 */
<BR> printf("%d\t",*b[0]);
<BR> printf("\n");
<BR> for (i=0; i<2;
i++) {
<BR> b=a+i;
/* 修改b的指向, 每次跳过二维数组的
<BR>
一行 */
<BR> printf("%d\t",*(b[i]+1));
<BR> }
<BR> printf ("\n");
<BR> }
<BR> 程序运行结果如下:
<BR> 9 13 17
21
<BR> 3 11 19
<BR>
<P> 3. 字符指针
<BR> 我们已经知道, 字符串常量是由双引号括起来的字符序列,
例如:
<BR> "a string"
<BR>就是一个字符串常量, 该字符串中因为字符a后面还有一个空格字符, 所以它由8
<BR>个字符序列组成。在程序中如出现字符串常量C 编译程序就给字符串常量按排一
<BR>存贮区域, 这个区域是静态的, 在整个程序运行的过程中始终占用, 平时所讲的
<BR>字符串常量的长度是指该字符串的字符个数, 但在按排存贮区域时, C 编译程序
<BR>还自动给该字符串序列的末尾加上一个空字符'\0', 用来标志字符串的结束,
因
<BR>此一个字符串常量所占的存贮区域的字节数总比它的字符个数多一个字节。
<BR> Turbo C中操作一个字符串常量的方法有:
<BR> (1). 把字符串常量存放在一个字符数组之中, 例如:
<BR> char s[]="a
string";
<BR>数组s共有9个元素所组成, 其中s[8]中的内容是'\0'。实际上, 在字符数组定义
<BR>的过程中, 编译程序直接把字符串复写到数组中, 即对数组s初始化。
<BR> (2). 用字符指针指向字符串, 然后通过字符指针来访问字符串存贮区域。
<BR>当字符串常量在表达式中出现时, 根据数组的类型转换规则, 它被转换成字符指
<BR>针。因此, 若我们定义了一字符指针cp:
<BR> char *cp;
<BR>于是可用:
<BR> cp="a string";
<BR>使cp指向字符串常量中的第0号字符a, 如图7.所示。
<BR>
cp
<BR> ┏━━━┓
┏━┳━┳━┳━┳━┳━┳━┳━┳━┓
<BR> ┃ ─╂─→
┃a ┃ ┃s ┃t ┃r ┃i ┃n ┃g ┃\0┃
<BR> ┗━━━┛
┗━┻━┻━┻━┻━┻━┻━┻━┻━┛
<BR>
图7.
<BR>以后我们可通过cp来访问这一存贮区域, 如*cp或cp[0]就是字符a, 而cp[i]或
<BR>*(cp+i)就相当于字符串的第i号字符, 但企图通过指针来修改字符串常量的行为
<BR>是没有意义的。
<BR>
<P> 4. 指针数组
<BR> 因为指针是变量, 因此可设想用指向同一数据类型的指针来构成一个数组,
<BR>这就是指针数组。数组中的每个元素都是指针变量, 根据数组的定义, 指针数组
<BR>中每个元素都为指向同一数据类型的指针。指针数组的定义格式为:
<BR> 类型标识 *数组名[整型常量表达式];
<BR> 例如:
<BR> int *a[10];
<BR>定义了一个指针数组, 数组中的每个元素都是指向整型量的指针, 该数组由10个
<BR>元素组成, 即a[0], a[1], a[2], ..., a[9], 它们均为指针变量。a为该指针数
<BR>组名, 和数组一样, a是常量, 不能对它进行增量运算。a为指针数组元素a[0]的
<BR>地址, a+i为a[i]的地址, *a就是a[0], *(a+i)就是a[i]。
<BR> 为什么要定义和使用指针数组呢? 主要是由于指针数组对处理字符串提供了
<BR>更大的方便和灵活, 使用二维数组对处理长度不等的正文效率低, 而指针数组由
<BR>于其中每个元素都为指针变量, 因此通过地址运算来操作正文行是十分方便的。
<BR> 指针数组和一般数组一样, 允许指针数组在定义时初始化,
但由于指针数组
<BR>的每个元素是指针变量, 它只能存放地址, 所以对指向字符串的指针数组在说明
<BR>赋初值时, 是把存放字符串的首地址赋给指针数组的对应元素, 例如下面是一个
<BR>书写函数month_name(n), 此函数返回一个指向包含第n月名字的字符指针( 关于
<BR>函数, 第6节将专门介绍)。
<BR> 例2: 打印1月至12月的月名:
<BR> char *month_name(int n)
<BR> {
<BR> static char
*name[]={
<BR>
"Illegal month",
<BR>
"January",
<BR>
"February",
<BR>
"March",
<BR>
"April",
<BR>
"May",
<BR>
"June",
<BR>
"July",
<BR>
"August",
<BR>
"September",
<BR>
"October",
<BR>
"November",
<BR>
"December"
<BR> };
<BR> return((n<1||n>12)?name[0]:name[n]);
<BR> }
<BR> main()
<BR> {
<BR> int i;
<BR> for(i=0; i<13;
i++)
<BR>
printf("%s\n", month_name(i));
<BR>
<hr color="#EE9B73" size="1" width="94%">
</TD>
<TD CLASS="tt3" VALIGN="bottom" width="8%" bgcolor="#e0e0e0"><strong><A HREF="015.htm">后一页</A><BR>
<A HREF="013.htm">前一页</A><BR>
<A HREF="index.html">回目录</A><BR>
<A HREF="../../../../index.htm">回首页</A><BR>
</strong>
</TD>
</TR>
</table>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -