C语言设计

第39章


谭浩强      C 语言程序设计               2001 年 5 月 1 日
前面介绍过,C语言允许把一个二维数组分解为多个一维数组来处理。因此数组 a 可分
解为三个一维数组,即 a[0],a[1],a[2]。每一个一维数组又含有四个元素。
例如 a[0]数组,含有 a[0][0],a[0][1],a[0][2],a[0][3]四个元素。
数组及数组元素的地址表示如下:
从二维数组的角度来看,a 是二维数组名,a 代表整个二维数组的首地址,也是二维数
组 0 行的首地址,等于 1000。a+1 代表第一行的首地址,等于 1008。如图:
a[0]是第一个一维数组的数组名和首地址,因此也为 1000。*(a+0)或*a 是与 a[0]等效
的, 它表示一维数组 a[0]0 号元素的首地址,也为 1000。&a[0][0]是二维数组 a 的 0 行 0
列元素首地址,同样是 1000。因此,a,a[0],*(a+0),*a,&a[0][0]是相等的。
同理,a+1 是二维数组 1 行的首地址,等于 1008。a[1]是第二个一维数组的数组名和首
地址,因此也为 1008。&a[1][0]是二维数组 a 的 1 行 0 列元素地址,也是 1008。因此
a+1,a[1],*(a+1),&a[1][0]是等同的。
由此可得出:a+i,a[i],*(a+i),&a[i][0]是等同的。
此外,&a[i]和 a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素 a[i]的地
址,不存在元素 a[i]。C语言规定,它是一种地址计算方法,表示数组 a 第 i 行首地址。
由此,我们得出:a[i],&a[i],*(a+i)和 a+i 也都是等同的。
另外,a[0]也可以看成是 a[0]+0,是一维数组 a[0]的 0 号元素的首地址,而 a[0]+1
则是 a[0]的 1 号元素首地址,由此可得出 a[i]+j 则是一维数组 a[i]的 j 号元素首地址,它
等于&a[i][j]。
谭浩强      C 语言程序设计               2001 年 5 月 1 日
由 a[i]=*(a+i)得 a[i]+j=*(a+i)+j。由于*(a+i)+j 是二维数组 a 的 i 行 j 列元素的首
地址,所以,该元素的值等于*(*(a+i)+j)。
【例 10.22】
main(){
    int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
    printf("%d,",a);
    printf("%d,",*a);
    printf("%d,",a[0]);
    printf("%d,",&a[0]);
    printf("%d ",&a[0][0]);
    printf("%d,",a+1);
    printf("%d,",*(a+1));
    printf("%d,",a[1]);
    printf("%d,",&a[1]);
    printf("%d ",&a[1][0]);
    printf("%d,",a+2);
    printf("%d,",*(a+2));
    printf("%d,",a[2]);
    printf("%d,",&a[2]);
    printf("%d ",&a[2][0]);
    printf("%d,",a[1]+1);
    printf("%d ",*(a+1)+1);
    printf("%d,%d ",*(a[1]+1),*(*(a+1)+1));
}
2. 指向多维数组的指针变量
把二维数组 a 分解为一维数组 a[0],a[1],a[2]之后,设 p 为指向二维数组的指针变量。
可定义为:
          int (*p)[4]
它表示 p 是一个指针变量,它指向包含 4 个元素的一维数组。若指向第一个一维数组
a[0],其值等于 a,a[0],或&a[0][0]等。而 p+i 则指向一维数组 a[i]。从前面的分析可得
出*(p+i)+j 是二维数组 i 行 j 列的元素的地址,而*(*(p+i)+j)则是 i 行 j 列元素的值。
二维数组指针变量说明的一般形式为:
谭浩强      C 语言程序设计               2001 年 5 月 1 日
类型说明符  (*指针变量名)[长度]
其中“类型说明符”为所指数组的数据类型。“*”表示其后的变量是指针类型。“长度”表示
二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。应注意“(*指
针变量名)”两边的括号不可少,如缺少括号则表示是指针数组(本章后面介绍),意义就完
全不同了。
【例 10.23】
main(){
    int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
    int(*p)[4];
    int i,j;
    p=a;
    for(i=0;i<3;i++)
{for(j=0;j<4;j++) printf("%2d  ",*(*(p+i)+j));
printf(" ");}
}
10.4 字符串的指针指向字符串的针指变量
10.4.1 字符串的表示形式
在 C 语言中,可以用两种方法访问一个字符串。
1) 用字符数组存放一个字符串,然后输出该字符串。
【例 10.24】
main(){
  char string[]=”I love China!”;
  printf("%s ",string);
}
说明:和前面介绍的数组属性一样,string 是数组名,它代表字符数组的首地址。
2) 用字符串指针指向一个字符串。
【例 10.25】
main(){
  char *string=”I love China!”;
  printf("%s ",string);
}
谭浩强      C 语言程序设计               2001 年 5 月 1 日
字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。只能按对指针
变量的赋值不同来区别。对指向字符变量的指针变量应赋予该字符变量的地址。
如:
    char c,*p=&c;
表示 p 是一个指向字符变量 c 的指针变量。
而:
    char *s="C Language";
则表示 s 是一个指向字符串的指针变量。把字符串的首地址赋予 s。
上例中,首先定义 string 是一个字符指针变量,然后把字符串的首地址赋予 string(应
写出整个字符串,以便编译系统把该串装入连续的一块内存单元),并把首地址送入 string。
程序中的:
char *ps="C Language";
等效于:
char *ps;
ps="C Language";
【例 10.26】输出字符串中 n 个字符后的所有字符。
main(){
  char *ps="this is a book";
  int n=10;
  ps=ps+n;
  printf("%s ",ps);
}
运行结果为:
book
谭浩强      C 语言程序设计               2001 年 5 月 1 日
在程序中对 ps 初始化时,即把字符串首地址赋予 ps,当 ps= ps+10 之后,ps 指向字符
“b”,因此输出为"book"。
【例 10.27】在输入的字符串中查找有无‘k’字符。
main(){
  char st[20],*ps;
  int i;
  printf("input a string: ");
  ps=st;
  scanf("%s",ps);
  for(i=0;ps[i]!="";i++)
    if(ps[i]=="k"){
       printf("there is a "k" in the string ");
       break;
    }
  if(ps[i]=="") printf("There is no "k" in the string ");
}
【例 10.28】本例是将指针变量指向一个格式字符串,用在 printf 函数中,用于输出二维
数组的各种地址表示的值。
小说推荐
返回首页返回目录