<>文章概述
本文章讲述关于C语言的主要内容如下:
   1.字符数组、2.一维数组与指针、3.二维数组与指针、4.字符串与指针、5.字符串指针数组
 <>一、字符数组
  定义一维数组时,系统会在内存中为其分配一段存储空间,数组名就是数组在内存中的首地址
。数组中的元素类型为字符型时,称为字符数组。字符数组中的每个元素可以存放一个字符。
注意:单引号‘’用来表示字符,双引号“”用来表示字符串
 <>1、字符数组定义和引用
定义形式如下:
 char 数组标识符[常量表达式]
示例:
char cArray[5]; // 字符数组的引用 cArray[0]='H',cArray[1]='e',cArray[2]='l',cArray[3]=
'l',cArray[4]='o'; 
对字符数组进行初始化操作时,有以下几种方法:
 (1)逐个字符赋给数组中的元素,例如:
char cArray[5]={'H','e','l','l','o'}; 
定义字符数组的同时进行初始化,此时可以省略数组长度,系统会自动根据初值个数来确定数组长度:
char cArray[]={'H','e','l','l','o'}; 
(2)利用字符串给字符数组赋值,例如:
char cArray[]={"Hello"}; 
或者将“{}”去掉,写成:
char cArray[]="Hello"; 
 <>2、字符数组的结束标志
在C语言中,使用字符数组保存字符串时,系统会自动为其添加“\0”作为结束符。即用字符串方式赋值比用字符逐个赋值要多占一个字节。
 char cArray[]=“Hello”;
 等价于:
 char cArray[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’};  //此时,占用6个字节
 <>3、字符数组的输入和输出
字符数组的输入和输出可以使用两种格式字符:“%c”和“%s”:
   1)%c可实现数组中字符的逐个输入与输出;
   2)%s可将整个字符串输入或输出;
使用格式字符“%s”输出字符串时,需要注意以下几种情况:
 * 输出字符中不包括结束符“\0”;
 * printf函数中的输出项是字符数组名cArray,而不是数组中的元素名cArray[0]等;
 * 即使数组长度大于字符串实际长度,也只会输出到“\0”为止; 
 <>二、数组与指针
  使用数组是,系统需要提供一段连续的内存来存储数组中的各元素,如果把数组的地址赋给指针变量,就可以通过指针变量来引用数组。
 <>1、一维数组与指针
将数组的首地址传给指针变量,则该指针就指向了这个一维数组。例如:
int *p,a[5]; p=a 
这里a是数组名,即数组的首地址,将它赋给指针变量p,即将a的首地址赋给p,也可以写成如下形式:
int *p,a[5]; p=&a[0]; 
上述两条赋值语句的操作效果完全相同。基于上述语句,有以下几种描述:
 * p+n与a+n都用于表示数组元素a[n]的地址,即&a[n]
 * *(p+n)和*(a+n)都用于表示数组元素a[n]的值 
 <>2、指针的移动“++”与“–”
采用指针自增运算实现时,需要注意:
   p++与p–可用于表示数组的输入
   *p++与*p–可用于表示数组的输出,
示例代码:
#include<stdio.h> int main() { int *p,a[5],i; p=a; printf("please input array 
a:\n"); for(i=0;i<5;i++){ scanf("%d",p++); //利用p++形式输入数组a } printf("%d\n",p); p=
a; /* 注意这一行 */ printf("%d\n",p); printf("array a is:\n"); for(i=0;i<5;i++){ 
printf("%5d",*p++); //利用*p++形式输出数组a } printf("\n"); return 0; } 
返回结果,如下:
需要注意的地方:
   如果在给数组元素赋值时使用了指针自增运算,而在后续步骤中也使用指针变量,此时的指针p指向数组a+4的地址。
   因此,需要再一次使用<p=a;>语句,将指针p重新指向数组a的首地址。
 <>3、二维数组与指针
对于一个m行n列的二维数组,其元素地址的表示方法如下:
 * a表示二维数组的首地址,a+i表示第i+1行的首地址;
 * a[i]+j表示数组第i+1行第j+1个元素的地址;
 * &a[0]表示数组第1行的首地址;
 * &a[0][0]既可以表示数组第1行第1列的首地址,也可以看作整个数组的首地址; 
指针也可表示地址,因此通过指针可以引用二维数组中的元素:
 * *(*(a+m)+n)和*(a[m]+n)含义相同,都表示数组第m+1行第n+1列元素
 * *(a+m)+n和a[m]+n含义相同,都表示数组第m+1行第n+1列元素的地址 
代码示例:
 将一个3行2列的二维数组打印出来:
#include<stdio.h> int main() { int i,j,(*p)[2]; int a[3][2]={{1,'a'},{2,'b'},{3
,'c'}}; p=a; for(i=0;i<3;i++){ for(j=0;j<2;j++){ if(j==0){ printf("%d, ",*(*(p+i
)+j)); } else{ printf("%c",*(*(p+i)+j)); } } printf("\n"); } return 0; } 
运行结果如下:
1, a 2, b 3, c 
 <>三、字符串指针数组
 <>1、字符串与指针
可以通过两种方式访问字符串,一是使用字符数组,二是使用字符指针。
 利用字符型指针输出字符串“hello”,具体代码如下:
#include <stdio.h> int main() { char *myStr="hello"; printf("%s\n",myStr); 
printf("%c\n",myStr[1]); //输出该字符串中第2个字符 return 0; } 
运行结果如下:
hello e 
 <>2、字符串数组
  字符串数组有别与字符数组。字符数组是一个一维数组,而字符串数组是以字符串作为数组元素的数组,可以将其看成一个二维字符数组
代码示例:
char cName[5][20]= { "zhangsan", "lisi", "wangwu", "luliu", "hongqi" } 
上述代码中,字符串数组变量cName被定义为含有5个字符串的数组,每个字符串的长度都必须小于20(这里需要考虑字符串最后的“\0”,也要占一个字节)
 <>3、字符串指针数组
  基于上述字符串数组的代码示例,可以发现,像“lisi”这样的字符串的长度仅为4,加上字符串结束符也仅为6。而内存中却要给它们各分配一个20字节的空间,空间浪费很大。
   为了解决这个问题,可以使用指针数组,使每个指针指向所需要的字符常量。这种方法需要在数组中保存字符指针,虽然也占用空间,但要远少于字符串数组占用的空间。
指针数组的定义:
   一个数组,如果其元素均为指针类型数据,则该数组称为指针数组。即指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义如下:
类型名* 数组名[数组长度] 
代码示例:
#include <stdio.h> int main() { int i; char *cName[]={"zhangsan","lisi",
"wangwu","luliu","hongqi"}; for(i=0;i<5;i++){ printf("%s\n",cName[i]); } return 
0; } 
运行结果,如下:
zhangsan lisi wangwu luliu hongqi 
 <>4、字符串数组与字符串指针数组的区别
举个栗子:
 char a[2][2] = {“hello”, “world”};  //字符串数组,存放的是字符
 char *b[] = {“hello”, “world”};   //字符串指针数组,存放的是指针即元素地址,指针指向其中的元素
char arra[5][20]; char *arrb[5]; 
两者在内存分配上的区别:
 * arra是一个字符串数组,分配内存5*20=100个字节
 * arrb是一个指针数组,分配内存5*8=40个字节 
两者在元素访问上的区别:
 * arra[2][0];
 *arrb[2];
 都是用于访问各自数组中第3行的首字符;
 * arra[2];
 arrb[2];
 都是用于表示第3行的字符串
 arra[2]是字符指针常量,arrb[2]是字符指针变量;
 * char (*parra)[20];
 char **parrb;
 parra=arra+2;
 parrb=arrb+2;
 定义了两个变量parra、parrb,分别接收了两个数组第3行的数据
 parra指向第3行占20个字符的一维数组
 parrb指向第3行的一个指针
**parrb指向第3行的首字符,*(*parrb+i)指向第3行第i+1个字符 
代码示例:
#include <stdio.h> int main() { char *cName[]={"zhangsan","lisi","wangwu",
"luliu","hongqi"}; printf("%c\n",*cName[2]); printf("%s\n",cName[2]); char **
pcName; pcName=cName+2; printf("%c\n",**pcName); printf("%c\n",*(*pcName+2)); 
return 0; } 
运行结果,如下:
w wangwu w n 
 <>5、字符串数组与指针数组的运用
代码示例:
#include <stdio.h> int main() { char cName[5][20]={"zhangsan","lisi","wangwu",
"luliu","hongqi"}; // 指针数组定义了5个元素 char *iArray[5]; // 指针数组定义了5个元素 iArray[1]=
cName[1]; // strcpy(iArray,"luliu"); // 当iArray[0]未指向字符串变量的地址时,该行代码是错误的写法 strcpy
(iArray[1],"xiaoer"); printf("%s\n",cName[0]); printf("%s\n",cName[1]); printf(
"%s\n",iArray[1]); return 0; } 
注意:当iArray[i]未指向任何字符串变量的地址时,不能将其拿来调用!
运行结果,如下:
zhangsan xiaoer xiaoer