C语言基础之数组

来源:互联网 发布:java报表框架 编辑:程序博客网 时间:2024/05/16 10:35

在C语言中,数组属于构造数据类。数组元素可以是基本数据类型也可以是构造类型。


一维数组定义:

  类型标识符 数组名[常量表达式]

  例: int a[10]            /*下标从0开始


  数组元素的表达式为:  数组名[下标]        /*下标可以是整型常量或者表达式

  数组元素初始化

  1.在定义数组时赋初值  例:int a[10]={0,1,2,3,4,5,6,7,8,9};

  2.给数组部分元素赋值  例:static int a[5]={7,6};   /*表明只给两个元素赋值,即a[0]=7,a[1]=6,其他值自动为0

  3.对全部元素赋初值时,可以不指定数组长度  例: static int a[]={1,2,3,};

  4.只能给元素逐个赋值,不能给数组整体赋值 即不能写成 int a[10]=1;

  

例:求数组中的最大值

#include<stdio.h>

main()

{

int a[10], i,max,id;

printf("Please input data:/n");

for(i=0;i<10;i++)

scanf("%d",&a[i]);

max=a[0]; id=0;

for(i=0;i<10;i++)

if(a[i]>max)

{

max=a[i]; id=i;

}

printf("The max number is:%d\nThe order is:%d\n",max,id);


例:十进制转八进制

分析:十进制转八进制的方法是把十进制不断地整除8,直到商为0为止,每次整除后的余数构成了相应的

八进制数(由低位到高位)的第一位,第二位…,定义一个一位数组,将计算后的八进制证书的每位数存储在数组中,当转换结束后,逆序输出数组内容即可。

main()

{

int decimal,i,j,trans[20];

printf("Please input a decimal number:\n");

scanf("%d,&decimal");

i=0;

while(decimal!=0)

{

trans[i++]=decimal%8;

decimal/=8;

}

for(j=i-1;j>=0;j--)

printf("%d\n",trans[j]);

}


字符数组的定义和初始化

由于字符型和整型通用, char a[5]也可以定义为 int a[5] 但这时每个数组元素占2个字节的内存单元

字符数组也可以是二维或多维数组

初始化: char c[10]={'c',' ','p','r','o','g','r','a','m'};   //不足的自动赋0值

当对全体元素赋初值时也可省去长度说明


字符数组的引用

(1)格式化输入是缓冲读,必须在接收到回车命令的时候,scanf()才开始读取数据。

(2)读字符数据时,空格是有效字符,被保存进字符数组

(3)按enter键时,输入的字符少于scanf()循环读取的字符时,scanf()继续等待用户将剩下的字符输入,

多余的话,scanf()只将前面的字符读入

(4)逐个读入字符结束后,不会自动在末尾加‘\0’。所以输出时,最好也是用逐个字符输出。

在scanf()和printf()函数中用格式字符%s整体输出字符串,一次调用者两个函数,便可以实现字符串的整体输入输出。


源程序:

#include "stdio.h"

main()

{

char str[5];

for(i=0;i<5;i++)

scanf("%c",&str[i]);

for(i=4;i>=0;i--)

printf("%s",str[i]);

}


运行结果:

hello

olleh

系统自动在字符串末尾增加一个‘\0’C语言规定数组名代表数组元素在内存中连续存在的起始地址,因此在scanf()函数中直接用str即可

说明:

(1)系统自动在字符串末尾加一个‘\0’,它只代表字符串的结束,它本身不是字符串的组成部分。

(2)按照%s格式输入字符串时,自动在最后加字符结束标志,并且可用%c格式逐个输出或用%s格式整体输出

(3)用%s格式输入字符串时,scanf和printf韩式的参数都要求字符串数组的首地址,即字符数组名。

(4)如果数组长度大于字符串实际长度,也只输出到\0结束

(5)按照%s格式输出字符串时,输出的字符串不能有空格,空格是输入数据的结束标志。这时scanf函数会认为输入的是两个字符串,如果要

输入含有空格的字符串可以使用系统标准函数gets().

例:

char s1[5],s2[5],s3[5];

scanf("%s%s%s\n",s1,s2,s3);

输入数据:

how are you

how\0 are\0 you\0 s1,s2,s3存储结构


如果改为

char str[13];

scanf("%s",str);

how\0         


字符串

字符串在c中没有专门的字符串变量,通常用一个字符数组来存放一个字符串,字符串总是以\0作为串的结束符

C语言中允许用字符串的方式对数组作初始化赋值

例: char c[]={‘c’,‘ ’,‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};

可写成 char c[]={"c program"};

或 char c[]="c program";

用字符串赋值比用字符逐个赋值要多占一个字节,用于存放字符串结束标志\0.


例:

main()

{

char str[15];

printf("input string:\n");

scanf("%s",str);

printf("%s\n",str)

}

说明:本例中定义的数组长度是15,因此输入的字符串长度必须小于15,以留出一个字节用于存放字符串结束标志\0,

当scanf函数输入字符串时,字符串中不能有空格,否则以空格作为串的结束符。为了避免这种情况,可多设几个字符数组分段以存放空格的串。

在前面介绍过,scanf的各输入项必须以地址的方式出现,如&a等,但在前例中却以数组各方式出现,因为在C语言中规定,数组名就代表了该

数组的首地址,整个数组是以首地址开头的一块连续的内存单元。


字符串操作常用的库函数

1.puts(字符数组名);   //把字符数组中的字符串输出显示到显示器,可以使用转义字符\n等

2.gets(字符数组名);  //从标准输入设备键盘上输入一个字符串,并不以空格作为输入结束标志


例:

char st[15];

printf("input string:\n");

gets(st);

puts(st);

3.strcat(字符数组名1,字符数组名2);  

功能:将2 中的字符链接到1 的后面并去掉1 中的结束符\0,函数返回是字符数组1 的首地址。注意1必须定义足够长度,否则有可能不能装下2.

4.strcopy(字符数组名1,字符数组名2);

功能:把2中的字符串赋值到1中,串结束符\0也一起复制。

5.strcmp(字符数组名1,字符数组名2);

功能:按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。

1=2,返回值=0;

1>2,返回值>0;

1<2,返回值<0;

6.strlen(字符串数组名)

功能:测字符串的实际长度(不包含结束符),并作为函数返回值


字符串常用算法

1.字符传计数

int countchar(char list[])

{

int i,count=0;

for(i=0;list[i]!='\0';i++)

count++;

return(count);

}

2.单词计数

int countword(char list[])

#define YES 1

#define NO 0

{

int i,inaword,count=0;

inaword=NO;

for(i=0;list[i]!='\0';i++)

{

if(list[i]!=' ')

inaword=NO;

else if(inaword==NO)

{

inaword=YES;

coumt++;

}

}

return(count);

}


3.逆序字符串

for(n=0;str[n]!='\0';n++)  //这个语句在这计算出str数组中的实际字符的个数

for(i=0,j=n-1;i<j;i++,j--)

{

c=str[i];

str[i]=str[j];

str[j]=c;

}


二维数组

因实际的硬件存储器是连续编址的,所以数据放完一行顺次放入第二行。。

二维数组初始化

1.分段赋值:int a[5][3]={{80,75,92},{61,65,71},{68,65,41},{85,61,87},{76,77,85}}

2.连续赋值:int a[5][3]={80,75,92,61,65,71,68,65,41,85,61,87,76,77,85}

3.对部分元素赋值,未赋值部分取0

int a[3][3]={{1},{2},{3}}

4.如对全部元素赋值 ,第一行长度可不给

int a[3][3]={1,2,3,4,5,6,7,8,9}

可写成int a[][3]={1,2,3,4,5,6,7,8,9}

5.a[3][4]可以分解成3个一维数组,器数组名为a[0],a[1],a[2]

这三个一维数组不需要另外说明即可使用,它们是数组名,不是一个单纯的下标变量


例:冒泡排序:数据由最小值排到最大值

#include<stdio.h>

#define SIZE 10   //定义数组的大小以及进入循环判断的条件

void main()

{

int a[SIZE]={2,3,4,13,10,12,85,68,53,37};

int i,pass,hold;

printf("Data items in original order:\n");

for(i=0;i<SIZE;i++)          //用来输出原始顺序的数据

printf("%4d",a[i]);

for(pass=1;pass<SIZE;pass++) //用来控制查找次数

for(i=0;i<SIZE-1;i++)    //进行两个相邻数据的比较

if(a[i]>a[i+1])

{

hold=a[i];

a[i]=a[i+1];

a[i+1]=hold;

}

printf("Data items in ascending order:\n");

for(i=0;i<SIZE;i++

printf("%4d",a[i]);

00return 0;

}


例:选择排序

选择排序就是找出数组中的最小值与第0个值对换,再从剩下的数中找出最小的数与第一个数对换等。

main()

{

int i,j,p,q,s,n,a[5]={25,65,21,45,58};

for(i=0;i<5;i++)

{

p=i;q=a[i];

for(j=i+1;j<5;j++) //每一次循环都是找出最大值放在i位

if(q<a[j])

{

p=j;q=a[j];

}

if(p!=i)

{

s=a[i];

a[i]=a[p];

a[p]=s;

}

}