说起数组,那可真是一点都不陌生,不管C语言中是重要的基础,在高级语言中依然是比较常用的基础课程之一,与之后的指针更是有着不解之缘。它是我们之后要学的线性结构中物理结构存储的基础。所以我说它是数据寄生的巢穴,是研究物理结构最常用的模型。
你如果还在因为数组的问题而担心的话,那就一起来看看今天的内容吧!我们今天的菜有:一维、二维数组的基本定义、初始化和引用;字符数组的输入输出以及比较常用的几个字符串处理函数。怎么样,还算丰盛吧!
1形式定义
类型 数组名【常量表达式】
比如:int a[10];定义了一个10个空间的一维数组,但是需要注意的是,虽然是10个空间,但其下标从0开始,即:a[0],a[1]......a[9]这10个。
2声明数组注意问题
(1)声明数组时,数组大小必须用常量表达式,可以是常量或者#define定义的常量,sizeof表达式也被认为是整数常量,但const值却不是常量(C++中是)。例如,
float a1[sizeof(int)+1]; float a2[(int)2.5];
|
#define SIZE 4 int main(void) { int arr[SIZE]; ... }
|
表格中的两种定义方式都是正确的。但是下面的定义是错误的:
main() { int n=5; int a[n]; } |
(2)如果是在函数中(不包括主函数)定义数组,其大小可以是变量或非常量表达式,例如:
void func(int n) { int a[2*n]; } |
3数组初始化
(1)int a[5]={0,1,2,3,4}; 相当于a[0]=0,a[1]=1.....a[4]=4
(2)只给部分元素赋值。int a[5]={0,1,2};表示只给a[0]~a[2]赋值。后面的a[3]~a[4]自动赋值为0.
(3)只能给元素逐个赋值,不能给数组整体赋值。
比如:给5个元素全部赋1.只能写成int a[5]={1,1,1,1,1};不能写成int a[5]=1;
(4)如果给全部元素赋值的话,可以省略元素个数。
比如:int a[5]={0,1,2,3,4}可以写成int a[]={0,1,2,3,4};
4.一维数组元素的引用
(1)一般形式 数组名[下标] a[5]表示数组第6个元素的值
其中,下标只能为整型常量或者整型表达式,如为小数,C编译自动取整。
比如:a[5.2]相当于a[5]
(2)C语言中只能逐个使用下标变量,而不能一次引用整个数组。
比如:输出有10个元算的数组必须使用循环语句逐个输出。
for(i=0;i<10;i++) { printf("%d",a[i]); } |
而不能写成 printf("%d",a); 这种形式。
1.定义
int a[3][4]表示一个3行4列的二维数组
a[0][0],a[0][1],a[0][2],a[0][3]
a[1][0],a[1][1],a[1][2],a[1][3]
a[2][0],a[2][1],a[2][2],a[2][3]
注意的是,它在概念上是二维的,是在两个方向上变化的,在一个平面之中,而不是像一维数组那样只是一个向量,但是在C语言中,二维数组是按行排列的,即二维数组在计算机中是一行空间。
2. 二维数组的初始化
(1) 比如:int a[3][2]={{1,2},{3,4},{5,6}}
或者 int a[3][2]={1,2,3,4,5,6} 这两种方法都是一样的,其结果都是:
1 2
3 4
5 6
(2)可以只对部分元素赋初值,未赋值的元素自动取0.
比如:int a[3][3]={{1},{2},{3}}表示的是
1 0 0
2 0 0
3 0 0
(3)如果对全部的元素赋初值,则第一维的长度可以不给出,但是第二维的长度必须有。
比如:int a[3][4]={1,2,3,4,5,6,7,8,9} 可以写成int a[][4]={1,2,3,4,5,6,7,8,9}
3.二维数组的引用
程序实例:
张 |
王 |
李 |
赵 |
周 |
|
Math |
1 |
2 |
3 |
4 |
5 |
C |
5 |
6 |
7 |
8 |
9 |
Foxpro |
10 |
11 |
12 |
13 |
14 |
设计一个二维数组a[3][5]来存放五个人的三门课成绩。再设计一个v[3]存放各科的平均成绩average。
#include <stdio.h> main() { int i,j,s=0,aver,v[3],a[3][5]; printf("input score\n"); for(i=0;i<3;i++) { for(j=0;j<5;j++) { scanf("%d",&a[i][j]); s=s+a[i][j]; } v[i]=s/5; s=0; } aver=(v[0]+v[1]+v[2])/3; printf("math:%d\nC:%d\nfoxpro:%d\n",v[0],v[1],v[2]); printf("total:%d\n",aver); } |
|
1.字符数组的定义
char c[10] 或者 char c[3][4]
字符数组和整型数组的定义是一样的,都分一维和二维数组,唯一的区别在于整型数组一个空间占2个字节,而字符数组分配的一个空间占1个字节
2.字符数组的初始化
char c[10]={'C,'','p','r','o','g','r','a','m'};
一共10个空间,我们只给出了前9个,最后一个系统会自动赋予空格。在计算机中的存储如下所示:
C |
p |
r |
o |
g |
r |
a |
m |
3.字符串与字符串结束标志
在C语言中没有专门的字符串变量,所谓的字符串是字符数组的一个组合体,然后加上一个‘\0’结束符。 比如:
char c[]={'C,'','p','r','o','g','r','a','m'};
可以写成 char c[]={“C program”};
也可以写成 char c[]=”C program”;
用字符串方式赋值比用字符逐个赋值要多占一个结束符的字节。上述的字符数组在计算机中实际是这样存储的:
C |
p |
r |
o |
g |
r |
a |
m |
\0 |
‘\0’是系统自动加上的,所以在用字符串赋值的时候一般无须指定数组的长度。
1. 除了上述我们说的用字符数组的方法给字符串赋值以外,我们大多都采用printf函数和scanf()函数一次性输出输入一个字符串,而不用使用循环语句;
比如: char c[]=”zhaoyuqiang”;
printf(“%s”,c); 需要注意的是,这儿的c不能写成c[]。这是错误的,因为%s已经代表了输出的是一个字符串。
2.需要注意的是,在用scanf()输入字符串时,空格代表的是结束符。
我们举一个例子:
#include <stdio.h> main() { char st[15]; printf("input string:\n"); scanf("%s",st); //注意输入的字符长度不要超过15-1(结束符)=14个字符长度 //st不要写成 &st,因为数组名代表数组首地址,所以不需要加取地址符了。在之后的指针我们再讲 printf("%s\n",st); //不要写成st[] }
|
|
在上述程序中,可以看到,我们明明定义了15个空间的大小,我们输入的也没有超过空间的大小,但是为什么只有zhao,而后面的空格和yuqiang竟然没有输出?
这就是在scanf()函数中,空格代表的是‘\0’,即结束符。
那就有人问了,如果我们非要输出空格怎么办。这个问题还好解决,多设置几个字符数组不就行了吗。我们可以将程序改成如下:
#include <stdio.h> main() { char st1[6],st2[10]; printf("input string:\n"); scanf("%s%s",st1,st2); printf("%s %s\n",st1,st2); //%s和%s之间加上一个空格 } |
|
如同格式输入与输出要添加头文件“stdio.h”一样, 字符串函数要添加头文件 “string.h”。
常用的字符串函数有如下几种:
1. gets()和puts() :字符串输入与输出函数
#include <stdio.h> #include "string.h" //头文件 main() { char st[16]; printf("input string:\n"); gets(st); //等价于scanf("%s",st); printf("输出"); puts(st); //等价于printf("%s\n",st); } |
|
上述程序备注中的gets()函数等价于scanf("%s",st); 但是它们有一个很大的不同,就是gets()函数可以不以空格作为结束符:我们还是以上述的程序,但是变化一下输入看看结果:
|
我们可以看到 输入的zhao和yuqiang之间加了空格,但是依然能够输出,这就是gets()和scanf()的区别。
2.字符串连接函数:strcat(数组名1,数组名2)
#include <stdio.h> #include "string.h" //头文件 main() { static char st1[30]="My name is "; char st2[10]; printf("请输入你的名字"); gets(st2); strcat(st1,st2);//将连个字符串连接起来,连接起来的新字符串的名字即可叫st1也可是st2 printf("显示"); puts(st1);//输入st1或者st2都是一样的结果 } |
|
3.字符串拷贝函数 :strcpy(字符数组名1,字符数组名2)
#include <stdio.h> #include "string.h" //头文件 main() { char st1[30],st2[]="zhao yuqiang"; printf("将st2中的内容复制到st1中\n"); strcpy(st1,st2);//将zhao yuqiang复制到st1中 puts(st1); puts("\n"); } |
|
4.求字符串长度函数:strlen(字符数组名)
#include <stdio.h> #include "string.h" //头文件 main() { char st1[]="zhao yuqiang"; //字符串长度不包括结束字符,并且该函数可以作为返回值直接返回 printf("st1中的字符串长度为:%d\n",strlen(st1)); } |
|
5.字符串比较函数:strcmp(字符数组名1,字符数组名2)
规则:
字符串1=字符串2 ,返回值=0; 字符串1>字符串2 ,返回值>0; 字符串1<字符串2 ,返回值<0; |
两个字符串比较,是按照ASCII中的大小比较的,先比较第一个字符,再比较第二个.......
#include <stdio.h> #include "string.h" //头文件 main() { static char st1[15],st2[]="zhao yuqiang"; int k; printf("请输入要和st2比较的字符串\n"); gets(st1); k=strcmp(st1,st2);//进行比较,结果返回给k if(k==0) printf("st1=st2\n"); if(k>0) printf("st1>st2\n"); if(k<0) printf("st1<st2\n"); } |
|