C语言数组与典型算法
一、一维数值数组
定义数组: 类型 数组名[数组长度];
如 int a[10];
1. a是数组名,代表所分配存储空间的首地址,即a<=>&a[0]
2. 定义了10个元素分配在连续的存储空间内,元素的下标范围0~10-1
3. 数组长度必须是常量或常量表达式
- 定义数组的同时可以给元素赋初值,赋初值的情况如下:
1) int a[10]={1,2,3,4,5,6,7,8,9,10};//全部元素赋初值
2) int a[10]={1,2,3,4}; //部分元素赋初值,未赋值元素初值为0
3) int a[10]={0}; //全部元素取得初值0
4) int a[10]; //未赋初值,所有元素取得随机值
5) int a[4]={1,2,3,4,5,6}; //初值个数多余元素个数,错误! - 使用数组元素的时候,下标可以是有效范围内的常量、变量、表达式
a[5] a[i] a[i+1]
二、二维数组
int a[3][4]
a[0][0] a[0][1] a[0][2] a[0][3] //a[0] <=> &a[0][0]
a[1]
a[2]
普通矩阵转置
int a[2][3],b[3][2],i,j;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
b[j][i]=a[i][j];
方阵转置,结果存于原矩阵
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
int a[4][4],i,j,t;
for(i=0;i<4;i++)
for(j=0;j<i;j++)
t=a[i][j],a[i][j]=a[j][i],a[j][i]=t;
main()
{
int x=1,y=0,a=0,b=0;
switch (x)
{
case 1: switch(y)
{
case 0:a++;break; //a=1
case 1:b++;break;
}
case 2:a++;b++;break; //a=2,b=1
case 3:a++;b++;
}
printf("a=%d,b=%d\n",a,b);
}
m=8;
int i,*p;
p=&i;
1,2,3,4,5,6,7,8,9,10
5 4 3 2 1 6 7 8 9 10
#include <stdio.h>
#define N 4
void fun(int a[][N],int b[])
{
int i;
for(i=0;i<N;i++)
b[i]=a[i][i]-a[i][N-1-i];
}
main() {
int x[N][N]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}},y[N],i;
fun(x,y);
for(i=0;i<N;i++) printf("%d,",y[i]);
printf("\n");
}
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
b[0]=a[0][0]-a[0][3]=-3
b[1]=a[1][1]-a[1][2]=-1
b[2]=a[2][2]-a[2][1]=1
b[3]=a[3][3]-a[3][0]=3
三、字符数组
字符串:“abc”
字符变量:char ch;
字符变量的赋值:ch=‘a’; ch=‘\101’; ch=65; ch=ch+32;
定义字符数组:char s[20];
字符数组赋初值:
char s[]={'a','b','c'}; //逐个字符赋值,s默认长度为3
char s[]="abc"; //以字符串形式赋初值,s默认长度为4
char ss[10][80]={"abc","xyz","12345"}; //二维字符数组可以存放多个字符串,一行存一个字符串
I/O:
逐个元素I/O: 结合循环 putchar(s[i]); s[i]=getchar();
printf或scanf 中 %c
整体I/O: puts 或gets
printf或scanf 中 %s格式
char s[]="abcde";
puts(s); <=> printf("%s\n",s);
gets() 接收以回车结束的字符串
scanf的%s 格式接收以回车或空格结束的字符串
字符串处理函数:包含在<string.h>头文件中
strcat(s1,s2);
char s1[80]="abcdef",s2[80]="xyz",i,j;
for(i=0;s1[i]!='\0';i++) ;
for(j=0;s2[j]!='\0';j++)
s1[i++]=s2[j];
s1[i]='\0' ;
strcat(s1,s2); // s1:abcdefxyz
strcat(s1+3,s2+1);// s1:abcdefyz
char s1[80]="abcdef",s2[80]="xyz"
strcpy(s1,s2);//字符串的赋值不能写成s1=s2; s1:xyz
strcpy(s1+3,s2); //s1:abcxyz
char s1[80]="abc",s2[80]="aBcde";
strcmp(s1,s2); //字符比较不能写成s1>s2,
if( strcmp(s1,s2) == 0 )
strlen(str); //求str字符数组中第一个空字符之前的字符个数
char s[]="12\08ab";
strlen(s) //值为2
sizeof(s) //值为7
i love china.
a aa aab abcde
统计一行字符的单词个数:
char str[80];
int n=0,i,word=0;
gets(str);
for(i=0;str[i]!='\0';i++)
if(str[i]== ' ')
word=0;
else if(word==0)
{
n++;
word=1;
}
典型算法:
1、求最值
求三个整数的最大数:
int a,b,c,m;
scanf("%d%d%d",&a,&b,&c);
m=a;
if(m<b) m=b;
if(m<c) m=c;
printf("max is %d\n",m);
求10个整数的最大数及其位置:
int a[10],i,m,k;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
m=a[0];k=0;
for(i=1;i<10;i++)
if(m<a[i]) m=a[i],k=i;
printf("max is %d at %d\n",m,k);
2、Fibonacci数列
int f[30]={1,1},i;
for(i=2;i<30;i++)
f[i]=f[i-1]+f[i-2];
3、筛选法求素数
4、数组元素逆置(反序存放):对折交换
int a[10]={1,2,3,4,5,6,7,8,9,10},i,j,t;
for( i=0,j=9 ; i<j ; i++,j-- )
{ t=a[i]; a[i]=a[j]; a[j]=t; }
5、折半查找:在一个有序序列中查找某个数据
int a[10]={1,6,8,11,16,18,22,30,35,40},low,high,mid,x;
low=0,high=9;
printf("请输入要查找的数:");
scanf("%d",&x);
while(low<=high)
{
mid=(low+high)/2;
if(x>a[mid]) low=mid+1;
else if(x<a[mid]) high=mid-1;
else break;
}
if(low>high)
printf("查无此数!\n");
else
printf("%d 在 %d 位置.\n",x,mid )
6、冒泡法排序:相邻元素两两比较,逆序交换
int a[10]={5,3,4,9,10,2,7,6,1,0},i,j,t;
for(i=0;i<9;i++)
for(j=0;j<9-i;j++)
if(a[j]>a[j+1])
t=a[j],a[j]=a[j+1],a[j+1]=t;
7、选择法排序
int a[10]={5,3,4,9,10,2,7,6,1,0},i,j,k,t;
for(i=0;i<9;i++)
{
k=i;
for(j=i+1;j<10;j++)
if(a[k]<a[j]) k=j;
t=a[i]; a[i]=a[k]; a[k]=t;
}