C程序设计
2024-04-01 14:28:30 0 举报
AI智能生成
C语言是一种广泛使用的程序设计语言,它具有简洁的语法和丰富的函数库,适合编写各种类型的程序,如系统程序、应用程序和图形用户界面程序。C语言程序通常由一个或多个函数组成,每个函数实现特定的功能。函数可以嵌套调用,也可以调用库函数。C语言的数据类型丰富,包括整数、浮点数、字符和数组等。通过指针,C语言可以方便地操作内存和动态分配内存。C语言还支持宏定义和条件编译,可以方便地编写跨平台的程序。C语言程序通过编译后生成可执行文件,可以在各种操作系统上运行。
作者其他创作
大纲/内容
循环结构
概述:
反复执行某段程序,知道某种条件不满足才结束
反复执行某段程序,知道某种条件不满足才结束
while语句
一般形式:
while(表达式)
语句;
while(表达式)
语句;
注意
在循环体中,应有使循环趋于结束的语句
程序陷入死循环,用Ctrl+break结束
循环体中如果包含一个以上的语句,需要用{}括起来
例题:
求sum=1+2+……+100
思路:
令sum表示被加数(初始值为0)令i表示教书(初始值为1)
进行100次加法后结束,或者单加数大于100时结束
sum中存放计算结果
求sum=1+2+……+100
思路:
令sum表示被加数(初始值为0)令i表示教书(初始值为1)
进行100次加法后结束,或者单加数大于100时结束
sum中存放计算结果
void main()
{
int sum=0,i=1;
printf("%d\n",sum);
while(i<=100)
{
sum=sum+i;
i++;
}
printf("sum=%d\n",sum);
}
{
int sum=0,i=1;
printf("%d\n",sum);
while(i<=100)
{
sum=sum+i;
i++;
}
printf("sum=%d\n",sum);
}
do……while语句
一般形式:
do
语句;
while(表达式)
do
语句;
while(表达式)
例题:
求sum=1+2+……+100
用do……while实现
求sum=1+2+……+100
用do……while实现
void main()
{
int sum=0,i=1;
do{
sum=sum+i;
i++;
} while(i<=100);
}
{
int sum=0,i=1;
do{
sum=sum+i;
i++;
} while(i<=100);
}
while与do……while的区别
do……while的循环体至少要执行一次,
而while中的循环体可能一次也不执行
而while中的循环体可能一次也不执行
for语句
一般形式:
for(表达式1;表达式2;表达式3)
语句;
表达式1是初始条件
表达式2是循环条件
语句是循环体
for(表达式1;表达式2;表达式3)
语句;
表达式1是初始条件
表达式2是循环条件
语句是循环体
先执行表达式1,表达式2判定条件,如果条件为真,执行语句,然后执行表达3
再判定条件,如果为真,在执行语句,在判定条件,直到为假,退出循环
再判定条件,如果为真,在执行语句,在判定条件,直到为假,退出循环
for(表达式1;表达式2;表达式3)
1.如果省略了“表达式1”(初始条件)表示不对循环控制变量赋初值
2.如果省略了“表达式2”(循环条件)不做其他处理时,便成为死循环
3.如果省略了“表达式3”(循环变量增加量)则不对循环控制变量进行操作,这时可在语句体中加入修改循环控制变量的语句
4.可以省略表达式1和表达式3
5.表达式1可以是设置循环变量的初值的赋值表达式,也可以是其他表达式
6.表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式
7.表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值非0,就执行循环体
1.如果省略了“表达式1”(初始条件)表示不对循环控制变量赋初值
2.如果省略了“表达式2”(循环条件)不做其他处理时,便成为死循环
3.如果省略了“表达式3”(循环变量增加量)则不对循环控制变量进行操作,这时可在语句体中加入修改循环控制变量的语句
4.可以省略表达式1和表达式3
5.表达式1可以是设置循环变量的初值的赋值表达式,也可以是其他表达式
6.表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式
7.表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值非0,就执行循环体
例:
求sum=1+2+……+100
用for循环改写
求sum=1+2+……+100
用for循环改写
int i,sum=0;
for(i=1;i<=100;i++)
sum=sum+i;
for(i=1;i<=100;i++)
sum=sum+i;
goto语句
一般形式:
goto 语句标号;
语句标号由字母、数字和下划线组成,不能使用整数
goto 语句标号;
语句标号由字母、数字和下划线组成,不能使用整数
四种循环结构的区别
它们都可以用来处理同一个问题,一般可以相互代替,不提倡用goto型循环
while和do……while循环,循环体应当包括使循环趋于结束的语句,for语句功能更强,用while完成的,用for都能实现
用while和do……while循环时,循环变量初始化的操作在while和do……while语句之前完成,而for语句可以在表达式1实现循环变量的初始化
while、do……while、for循环,都可以用break语句跳出循环,用continue语句结束本次循环
break语句和continue语句
break语句提前终止循环
例题:
在全校1000名学生中进行捐款,当总数达到10万元时结束,
统计捐款人数以及平均每人捐款
在全校1000名学生中进行捐款,当总数达到10万元时结束,
统计捐款人数以及平均每人捐款
#include<stdio.h>
#define SUM 100000
int main()
{
float amount,aver,total;
int i;
for(i=1,total=0;i<=1000;i++)
{
printf("输入捐款\n");
scanf("%f",&amount);
total=total+amount:
if (total>=sum) break;
}
aver=total/i;
printf("num=%d\n,aver=%10.2f\n",i,aver);
return 0;
}
#define SUM 100000
int main()
{
float amount,aver,total;
int i;
for(i=1,total=0;i<=1000;i++)
{
printf("输入捐款\n");
scanf("%f",&amount);
total=total+amount:
if (total>=sum) break;
}
aver=total/i;
printf("num=%d\n,aver=%10.2f\n",i,aver);
return 0;
}
用continue语句提前结束本次循环
有时并不想终止整个循环,而只是提前结束本次循环,
而接着执行下一次循环,这是可以用continue语句。
有时并不想终止整个循环,而只是提前结束本次循环,
而接着执行下一次循环,这是可以用continue语句。
例题:
输出100-200之间不能被3整除的数
输出100-200之间不能被3整除的数
void main()
{
int i;
for(i=100;i<=200;i++)
{
if(i%3==0)
continue;
printf("%d\t",i);
}
}
{
int i;
for(i=100;i<=200;i++)
{
if(i%3==0)
continue;
printf("%d\t",i);
}
}
break语句和continue语句的区别
continue语句只结束本次循环,而不是终止整个循环的执行
break语句结束整个循环过程,不在判断循环的条件是否成立
break语句结束整个循环过程,不在判断循环的条件是否成立
循环嵌套
一个循环体内又包含一个完整的循环结构,称为循环嵌套
内嵌的循环中还可以嵌套循环,这就是多层循环
例题:
输出下面的图形
*****
*****
*****
*****
*****
输出下面的图形
*****
*****
*****
*****
*****
void main()
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=5;j++)
printf("*");
printf(""\n);
}
}
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=5;j++)
printf("*");
printf(""\n);
}
}
例题:
输出下面图形
*
**
***
****
*****
输出下面图形
*
**
***
****
*****
void main()
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=i;j++)
printf("*");
printf("\n");
}
}
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=i;j++)
printf("*");
printf("\n");
}
}
例题:
输出下面图形
*
**
***
****
*****
输出下面图形
*
**
***
****
*****
void main()
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=5-i;j++)
printf(" ");
for(j=1;j<=i;j++);
printf("*");
printf("\n");
}
}
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=5-i;j++)
printf(" ");
for(j=1;j<=i;j++);
printf("*");
printf("\n");
}
}
例题:
输出下面图形
*
***
*****
*******
*****
***
*
输出下面图形
*
***
*****
*******
*****
***
*
void main()
{
int i,j;
for(i=1;i<=4;i++)
{
for(j=1;j<=4-i;j++)
printf(" ");
for(j=1;j<=2*i-1;j++);
printf("*");
printf("\n");
}
for(i=1;i<=3;i++)
{
for(j=1;j<=i;j++)
printf(" ");
for(j=1;j<=x*(4-i)-1;j++)
printf("*");
printf("\n");
}
}
{
int i,j;
for(i=1;i<=4;i++)
{
for(j=1;j<=4-i;j++)
printf(" ");
for(j=1;j<=2*i-1;j++);
printf("*");
printf("\n");
}
for(i=1;i<=3;i++)
{
for(j=1;j<=i;j++)
printf(" ");
for(j=1;j<=x*(4-i)-1;j++)
printf("*");
printf("\n");
}
}
循环常用算法分析
累加
例:求1+2+3+......+n
分析:求多项式之和,首先得设置一个累加器sum存放结果
sum=0 sum=sum+1 sum=sum+i
整个过程一直在重复执行sum=sum+i,一共重复n次
分析:求多项式之和,首先得设置一个累加器sum存放结果
sum=0 sum=sum+1 sum=sum+i
整个过程一直在重复执行sum=sum+i,一共重复n次
累乘
例:求10!
int main()
{
int i,j;
long jc=1;
for(i=1.i<=10,i++)|
jc=jc*i;
printf("jc=%id\n",jc);
return 0;
}
{
int i,j;
long jc=1;
for(i=1.i<=10,i++)|
jc=jc*i;
printf("jc=%id\n",jc);
return 0;
}
例:求1!+2!+3!+4!+5!
#include <stdio.h>
void main()
{
int i,j,sum=0,jec=1;
for(i=1,i<=5,i++)
jec=jec*i;
sum=sum+jec;}
printf("%d\n",sum)
}
void main()
{
int i,j,sum=0,jec=1;
for(i=1,i<=5,i++)
jec=jec*i;
sum=sum+jec;}
printf("%d\n",sum)
}
求最值
迭代法
例:求斐波那契数列的前40个数。这个数列的特点
第1,2个数为1,1.从第三个数 开始,该数是前两个数之和
F1=1 (n=1)
F2=2 (n=2)
Fn=Fn-1+Fn-2 (n>=3)
第1,2个数为1,1.从第三个数 开始,该数是前两个数之和
F1=1 (n=1)
F2=2 (n=2)
Fn=Fn-1+Fn-2 (n>=3)
void main()
{
int i,F1=1,F2=2,F3=0;
printf("%d\t,%d\t",F1,F2);
for(i=1,i<=38,i++)
{
F3=F1+F2;
printf("%d\t",f3);
F1=F2;
F2=F3;
}
}
{
int i,F1=1,F2=2,F3=0;
printf("%d\t,%d\t",F1,F2);
for(i=1,i<=38,i++)
{
F3=F1+F2;
printf("%d\t",f3);
F1=F2;
F2=F3;
}
}
素素问题
素素就是质数,一个大于1且只能被1和它本身整除的整数
例:输入一个大于3的整数n,判断它是否是素数
思路:
让n被i整除(i的值从2变到n-1)
如果n能被2~(n-1)之中任何一个数整除,则表示n肯定不是素数,
不必再进行后面的操作,可以用break提前结束循环
例:输入一个大于3的整数n,判断它是否是素数
思路:
让n被i整除(i的值从2变到n-1)
如果n能被2~(n-1)之中任何一个数整除,则表示n肯定不是素数,
不必再进行后面的操作,可以用break提前结束循环
void main()
{
int,i,n;
scanf("%d",&n);
for(i=2;i<=n-1;i++)
if(n%i==0)
{
printf("%d不是素数",n);
break;
}
if(i==n)
printf("%d是素数\n",n);
}
{
int,i,n;
scanf("%d",&n);
for(i=2;i<=n-1;i++)
if(n%i==0)
{
printf("%d不是素数",n);
break;
}
if(i==n)
printf("%d是素数\n",n);
}
求100~200间的全部素数
void main()
{
int,i,n;
for(i=100;i<=200;i++)
{
for(n=100;n<=i-1;n++)
if(i%n==0)
break;
if(i==n)
printf("%d\n",n);
}
}
{
int,i,n;
for(i=100;i<=200;i++)
{
for(n=100;n<=i-1;n++)
if(i%n==0)
break;
if(i==n)
printf("%d\n",n);
}
}
穷举法
水仙花数
设一个三位数可以表示为abc,若其能满足条件a^3+b^3+c^3=abc,
则称其为水仙花数,例如153。 153=1^3+5^3+3^3
例:编程求出所有得到水仙花数
设一个三位数可以表示为abc,若其能满足条件a^3+b^3+c^3=abc,
则称其为水仙花数,例如153。 153=1^3+5^3+3^3
例:编程求出所有得到水仙花数
void main()
{
int i,a,b,c;
for(i=100;i<=999;i++)
{
a=i%100;
b=i/10%10;
c=i%10;
if(a*a*a+b*b*b+c*c*c=i)
printf("%d\n",i);
}
}
{
int i,a,b,c;
for(i=100;i<=999;i++)
{
a=i%100;
b=i/10%10;
c=i%10;
if(a*a*a+b*b*b+c*c*c=i)
printf("%d\n",i);
}
}
例:百元买百鸡
公鸡五元一个,母鸡三元一个,小鸡一元三个
公鸡五元一个,母鸡三元一个,小鸡一元三个
void main()
{
int ,i,j,k,a;
for (i=1,i<=20;i++)
for(j=0;j<=34:j++)
for (k=0,k<=100;k++)
if(i+k+j==100&&i*5+i*3+k/3==100&&k%3==0)
printf("%\t,%d\t,%d\t\n",i,j,k);
}
{
int ,i,j,k,a;
for (i=1,i<=20;i++)
for(j=0;j<=34:j++)
for (k=0,k<=100;k++)
if(i+k+j==100&&i*5+i*3+k/3==100&&k%3==0)
printf("%\t,%d\t,%d\t\n",i,j,k);
}
字符统计
例:输入一个字符,分别统计出其中的英文字母、空格
数字和其他字符的个数
数字和其他字符的个数
void main()
{
int z=0,s=0,k=0,q=0;
char ch;
ch=getchar();
while (ch!='\n')
{
if (ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
z++;
else if(ch==' ')
k++;
else if (ch>='0'&&ch<='q")
s++;
else
q++;
ch=getchar();
}
printf("%d\t,%d\t,%d\t,%d\t\n",z,k,s,q);
}
{
int z=0,s=0,k=0,q=0;
char ch;
ch=getchar();
while (ch!='\n')
{
if (ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
z++;
else if(ch==' ')
k++;
else if (ch>='0'&&ch<='q")
s++;
else
q++;
ch=getchar();
}
printf("%d\t,%d\t,%d\t,%d\t\n",z,k,s,q);
}
译密码
例:输入一行字符,输出相应的密码
void main()
{
char ch;
ch=getchar();
while (ch!='\n')
{
if(ch>='w'&&ch<='z'||ch>='W'&&ch<='Z')
ch=ch+4-26;
else
ch=ch+4;
printf("%c",ch);
ch=getchar();
}
}
{
char ch;
ch=getchar();
while (ch!='\n')
{
if(ch>='w'&&ch<='z'||ch>='W'&&ch<='Z')
ch=ch+4-26;
else
ch=ch+4;
printf("%c",ch);
ch=getchar();
}
}
数组
一维数组
怎么定义一维数组
数组是一组有序数据的集合,数据中各组数据的排列是有一定规律的,
下表代表数据在数据中的型号
下表代表数据在数据中的型号
数组中的每一个元素都属于同一个数据类型
数组必须先定义后使用
定义一维数组的一般形式为:
类型符 数组名[常量表达式]
类型符 数组名[常量表达式]
数组名的命名规范和变量名相同
如: int a[10]
int 每个元素的数据类型
a 数组名
10 数组长度
10个元素 a[0],a[1],a[2],........,a[9]
如: int a[10]
int 每个元素的数据类型
a 数组名
10 数组长度
10个元素 a[0],a[1],a[2],........,a[9]
怎么引用一维数组元素
引用数组元素的表达式为
数组名 [下标]
数组名 [下标]
注意:
只能引用数组元素而不能一次整体调用整个数组全部元素的值
只能引用数组元素而不能一次整体调用整个数组全部元素的值
实现数组的复制
void main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10},b[10];
for (i=0;i<10;i++)
{
b[i]=a[i];
printf("%d",b[i]);
}
}
void main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10},b[10];
for (i=0;i<10;i++)
{
b[i]=a[i];
printf("%d",b[i]);
}
}
一维数组的赋值
给数组赋值的方法
用赋值语句对数组元素逐个赋值
采用初始化赋值
动态辅助(scanf())
一维数组的初始化
数组初始化赋值是指:
在数组定义时给数组元素赋予初值,数组初始化是在编译阶段进行的。这样减少运行时间,提高效率
在数组定义时给数组元素赋予初值,数组初始化是在编译阶段进行的。这样减少运行时间,提高效率
一般形式
类型说明符 数组名[常量表达式]={值,值,值,........,值}
其中{}中的各数据值即为各元素的初值,各值之间用,隔开
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
类型说明符 数组名[常量表达式]={值,值,值,........,值}
其中{}中的各数据值即为各元素的初值,各值之间用,隔开
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
说明
可以对全部数组元素赋值
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
可以只给一部分元素赋值
如 int a[10]={0,1,2,3,4};
只给前面5个元素赋值,后5个元素为0
如 int a[10]={0,1,2,3,4};
只给前面5个元素赋值,后5个元素为0
如果想使一个数组中全部元素为0,可以写成
如 int a[10]={0,0,0,0,0,0,0,0,0,0};或如 int a[10]={0};
不能写成a[10]=0
如 int a[10]={0,0,0,0,0,0,0,0,0,0};或如 int a[10]={0};
不能写成a[10]=0
在对全部数组元素赋值时,可以不指定数组长度
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
可以写成如 int a[]={0,1,2,3,4,5,6,7,8,9};
如 int a[10]={0,1,2,3,4,5,6,7,8,9};
可以写成如 int a[]={0,1,2,3,4,5,6,7,8,9};
一维数组的动态赋值
可以在程序执行过程中,对数组做动态赋值。
这时可以用循环语句配合scanf函数逐个对数组赋值
for (i=0;i<10;i++)
scanf("%d",&a[i]);
这时可以用循环语句配合scanf函数逐个对数组赋值
for (i=0;i<10;i++)
scanf("%d",&a[i]);
一位数组程序举例
例1:对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9
要求按逆序输出
要求按逆序输出
void main()
{
int i,a[10];
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
printf("%d",a[i]);
printf("\n");
return 0;
}
{
int i,a[10];
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
printf("%d",a[i]);
printf("\n");
return 0;
}
例2:将数组中的第一个元素与最后一个交换,
第二个元素与倒数第二个交换,依次类推
第二个元素与倒数第二个交换,依次类推
void main()
{
int ,i,t,a[10];
for (i=0;i<=9;i++)
a[i]=i;
for(i=0;i<10/2;i++)
{
t=a[i];
a[i]=a[9-i];
a[9-i]=t;
}
for(i=0;i<=9;i++)
printf("%d",a[i]);
}
{
int ,i,t,a[10];
for (i=0;i<=9;i++)
a[i]=i;
for(i=0;i<10/2;i++)
{
t=a[i];
a[i]=a[9-i];
a[9-i]=t;
}
for(i=0;i<=9;i++)
printf("%d",a[i]);
}
例3:求一维数组中最大元素及其下标
#define N
void main()
{
int score[N],i,max,m;
for(i=0;i<n;i++)
{
scanf("%d",&score[i]);
printf("%4d",score[i]);
}
max=score[0];
m=0;
for(i=0;i<N;i++)
{
if (score[i]>max)
{
max=score[i];
m=i;
}
}
printf("最大值是%d\n,最大值下标是%4d\n",max,m);
}
void main()
{
int score[N],i,max,m;
for(i=0;i<n;i++)
{
scanf("%d",&score[i]);
printf("%4d",score[i]);
}
max=score[0];
m=0;
for(i=0;i<N;i++)
{
if (score[i]>max)
{
max=score[i];
m=i;
}
}
printf("最大值是%d\n,最大值下标是%4d\n",max,m);
}
例4:用数组处理斐波那契数列问题
#define N 40
void main()
{
int f[N],i;
f[0]=f[1]=1;
printf("%d\n,%d\n",f[0],f[1]);
for (i=2;i<N;i++)
{
f[i]=f[i-1]+f[i-2];
printf("%d\n",f[i]);
}
}
void main()
{
int f[N],i;
f[0]=f[1]=1;
printf("%d\n,%d\n",f[0],f[1]);
for (i=2;i<N;i++)
{
f[i]=f[i-1]+f[i-2];
printf("%d\n",f[i]);
}
}
二维数组
二维数组的定义
类型说明符 数组名[常量表达式] [常量表达式]
int a[3] [4];
说明了一个三行四列的数组,数组名为a,类型是整型
int a[3] [4];
说明了一个三行四列的数组,数组名为a,类型是整型
我们可以把二维数组看做是一种特殊的一维数组:他的元素又是一维数组
二维数组在内存中的存放
二维数组在概念上是二维的,但是实际的硬件存储确实连续偏址的,
也就是说存储器单元是接受按一维线性排列的。二维数组是按行排列,
放完一行之后顺序放第二行
也就是说存储器单元是接受按一维线性排列的。二维数组是按行排列,
放完一行之后顺序放第二行
二维数组的引用
一般形式
数组名 [下标] [下标]
下标可以是整数表达式,a[2] [3],a[2-1] [2*2-1]
下标值应该在已定义的数组大小的范围内
数组名 [下标] [下标]
下标可以是整数表达式,a[2] [3],a[2-1] [2*2-1]
下标值应该在已定义的数组大小的范围内
二维数组的初始化
分行给二维数组赋初值
int a[3] [4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}
int a[3] [4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}
将所有数据写在一个华括弧内,按数组排列的顺序对各元素赋初值
int a[3] [4]={1,2,3,4,5,6,7,8,9,10,11,12}
int a[3] [4]={1,2,3,4,5,6,7,8,9,10,11,12}
可对部分元素赋初值
int a[3] [4]={{1},{2},{3}}
是对每一行的第一列元素赋值,未赋值的元素取0,
各元素的值为
1 0 0 0
2 0 0 0
3 0 0 0
int a[3] [4]={{1},{2},{3}}
是对每一行的第一列元素赋值,未赋值的元素取0,
各元素的值为
1 0 0 0
2 0 0 0
3 0 0 0
二维数组程序举例
例1:
有一个3*4的矩阵,求出最大值以及他的行号和列号
有一个3*4的矩阵,求出最大值以及他的行号和列号
void main()
{
int i,j,row,colum,max;
int a[3] [4]={{1,2,3,4},{9,8,7,6},{-10,-10,5,2}};
max=a[0] [0];
row=0;
colum=0;
for (i=0;i<=2;i++)
for(j=0;j<=3;i++)
if(a[i] [j]>max)
{
max=a[i] [j];
row=i;
colum=j;
}
printf("max=%d,row=%d,colum=%d\n",max,row,colum);
}
{
int i,j,row,colum,max;
int a[3] [4]={{1,2,3,4},{9,8,7,6},{-10,-10,5,2}};
max=a[0] [0];
row=0;
colum=0;
for (i=0;i<=2;i++)
for(j=0;j<=3;i++)
if(a[i] [j]>max)
{
max=a[i] [j];
row=i;
colum=j;
}
printf("max=%d,row=%d,colum=%d\n",max,row,colum);
}
例2:
将一个二维数组行和列的元素互换,存到另一个二维数组中
a=1 2 3 b=1 4
4 5 6 2 5
3 6
将一个二维数组行和列的元素互换,存到另一个二维数组中
a=1 2 3 b=1 4
4 5 6 2 5
3 6
int main()
{
int a[2] [3]={{1,2,3},{4,5,6}};
int b[3] [2],i,j;
printf("矩阵a是:\n");
for (i=0;i<=1;i++);
{
for (j=0;j<=2;j++)
{
printf("%5d",a[i] [j]);
b[i] [j]=a[i] [j];
}
printf("\n");
}
printf("矩阵b是\n");
for (i=0;i<=2;i++)
{
for (j=0;j<=1;j++)
printf("%5d",b[i] [j]);
printf("\n");
}
return 0;
}
{
int a[2] [3]={{1,2,3},{4,5,6}};
int b[3] [2],i,j;
printf("矩阵a是:\n");
for (i=0;i<=1;i++);
{
for (j=0;j<=2;j++)
{
printf("%5d",a[i] [j]);
b[i] [j]=a[i] [j];
}
printf("\n");
}
printf("矩阵b是\n");
for (i=0;i<=2;i++)
{
for (j=0;j<=1;j++)
printf("%5d",b[i] [j]);
printf("\n");
}
return 0;
}
例3:
有一个3*4的矩阵,要求将矩阵第一行与第三行对应元素减缓位置
有一个3*4的矩阵,要求将矩阵第一行与第三行对应元素减缓位置
void main()
{
int a[3] [4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int i,j,t;
printf("矩阵a是\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=3;j++)
printf("%5d",a[i] [j]);
printf("\n");
}
for(i=0;i<=3;i++)
{
t=a[0] [j];
a[0] [j];
a[2] [i]=t;
}
printf("交换后::\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
printf("%5d",a[i] [j]);
printf("\n");
}
{
int a[3] [4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int i,j,t;
printf("矩阵a是\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=3;j++)
printf("%5d",a[i] [j]);
printf("\n");
}
for(i=0;i<=3;i++)
{
t=a[0] [j];
a[0] [j];
a[2] [i]=t;
}
printf("交换后::\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
printf("%5d",a[i] [j]);
printf("\n");
}
例4:
求两个矩阵之和
求两个矩阵之和
void main()
{
int i,j,c[4] [4];
int a[4] [4]={{1},{2},{3},{4}};
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
c[i] [j]=(a[i] [j]+b[i] [j]);
}
for(i=0;i<4;i++)
{
for (j=0;j<4;j++)
printf("%5d",c[i] [j]);
printf("\n")
}
}
{
int i,j,c[4] [4];
int a[4] [4]={{1},{2},{3},{4}};
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
c[i] [j]=(a[i] [j]+b[i] [j]);
}
for(i=0;i<4;i++)
{
for (j=0;j<4;j++)
printf("%5d",c[i] [j]);
printf("\n")
}
}
字符数组
字符数组的定义
用来存放字符数据的数组。
字符数组中一个元素存放一个字符
字符数组中一个元素存放一个字符
定义形式
char c[10];
char c[10];
字符数组也可以是二维或多维数组
字符数组的初始化
逐个字符赋给数组中的各元素
char c[10]={'a',' ','c','d','e','f','g','b','q','r'};
char c[10]={'a',' ','c','d','e','f','g','b','q','r'};
如果花括号中提供的初值个数大于数组长度,则语法错误;
如果初值个数小于数组长度,只将这些字符赋给数组中前面那些元素,其余为'\0'
如果初值个数小于数组长度,只将这些字符赋给数组中前面那些元素,其余为'\0'
例如:
char c[10]={'a',' ','b','c','d','e','f','g','h'}
则c[0]='a',c[1]=' ',c[2]='b',c[3]='c',c[4]='d',c[5]='e'
c[6]='f',c[7]='g',c[8]='h',c[9]='\0'
char c[10]={'a',' ','b','c','d','e','f','g','h'}
则c[0]='a',c[1]=' ',c[2]='b',c[3]='c',c[4]='d',c[5]='e'
c[6]='f',c[7]='g',c[8]='h',c[9]='\0'
如果提供的初值个数与预定的数组长度相同,在定义时可以省略各数组长度,系统会自动
根据初值个数确实数组长度 char c[ ]={'a','b','c','e'}
根据初值个数确实数组长度 char c[ ]={'a','b','c','e'}
可以定义二维数组
例:输出一个字符串
void main()
{
char c[5]={'b',' ','o',' ','y'};
int i;
for (i=0;i<10;i++)
printf("%c",c[i]);
printf("\n");
}
void main()
{
char c[5]={'b',' ','o',' ','y'};
int i;
for (i=0;i<10;i++)
printf("%c",c[i]);
printf("\n");
}
字符串和字符串结束标志
在c语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串,有时,人们关心的是有效字符串的长度而不是字符数组的长度
例如,定义一个字符数组长度为100,而实际有效字符只有40个,为了测定字符串的实际长度,C语言规定可一个字符串结束标志,以字符'\0'代表
例如,定义一个字符数组长度为100,而实际有效字符只有40个,为了测定字符串的实际长度,C语言规定可一个字符串结束标志,以字符'\0'代表
可以把一个字符串直接赋给一个字符数组所表示的变量,已初始化字符数组
如 charc[]={"I am happy"}; 或者 char c[]="I am happy";
注意:
这里不用单个字符作为初值,而是用一个字符串作为初值。数组c的长度不是10,而是11,字符串常量的最后由系统加上一个'\0'
如 charc[]={"I am happy"}; 或者 char c[]="I am happy";
注意:
这里不用单个字符作为初值,而是用一个字符串作为初值。数组c的长度不是10,而是11,字符串常量的最后由系统加上一个'\0'
用字符串赋值比用字符逐个赋值要多占一个字节,用于存放字符串结束标志'\0'
例:分析 char c[10]={"china"};在内存中的存储
c h i n a \0 \0 \0 \0 \0
c h i n a \0 \0 \0 \0 \0
字符数组的输入输出
逐个字符输入输出。用格式符"%c"输入或输出一个字符
将整个字符串一次输入或输出。用"%s"格式符,意思是对字符串的输入输出
char c[]={"china"};
printf("%s",c);只输出"china"5个字符
char c[]={"china"};
printf("%s",c);只输出"china"5个字符
说明
用"%s"格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名或&
如果数组长度大于字符串实际长度,也只遇到'\0'结束
输出字符不包括结束符'\0'
如果一个字符数组中包含一个以上的'\0',则遇到第一个'\0'输出就结束
可以用scanf函数输入一个字符串
char c[20];
scanf("%s",c);
如果利用scanf输入多个字符串,则以空格分隔
char a[5],b[5],c[5];
scanf("%s%s%s",a,b,c);
输入数据: How are you ?
char c[20];
scanf("%s",c);
如果利用scanf输入多个字符串,则以空格分隔
char a[5],b[5],c[5];
scanf("%s%s%s",a,b,c);
输入数据: How are you ?
数组首地址
数组名代表了该数组的首地址。整个数组是以首地址开头一块的内存单元
数组名代表了该数组的首地址。整个数组是以首地址开头一块的内存单元
字符串处理函数
用于输入输出的字符串函数,在使用之前应包含头文件"stdio.h",使用其他字符串函数则应包含头文件"string.h"。
puts(str)
作用:
将一个字符串(以'\0'结束的字符序列)输出列到终端
char str[]={"china\nbeijing"};
puts(str);
输出 china
beijing
将一个字符串(以'\0'结束的字符序列)输出列到终端
char str[]={"china\nbeijing"};
puts(str);
输出 china
beijing
puts函数可以使用转义字符
puts函数可以由printf函数取代,
当需要按一定格式输入时,通常用printf
puts函数可以由printf函数取代,
当需要按一定格式输入时,通常用printf
gets(str)
作用:
从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址
如 gets(str)
从键盘输入 computer(回车)
从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址
如 gets(str)
从键盘输入 computer(回车)
注意:
用gets和puts函数只能输入或输出一个字符串
不能写成
puts(str1,str2)或gets(str1,str2)
用gets和puts函数只能输入或输出一个字符串
不能写成
puts(str1,str2)或gets(str1,str2)
当输入的字符串含有空格时,输出仍为全部字符串。
说明函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束
这是与scanf函数不同的。
说明函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束
这是与scanf函数不同的。
strcat()
格式:
strcat(字符数组名1,字符数组名2)
strcat(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,
并删除字符串1后的标志位'\0',结果放在字符数组1中。
并删除字符串1后的标志位'\0',结果放在字符数组1中。
字符数组1应定义足够的长度,否则不能全部装入被连接的字符串
gets() puts() strcat()的使用
#include<string.h>
int main()
{
char st1[30]="my name is";
char st2[10];
printf("输入你的名字:\n");
gets(st2)
strcat(st1);
}
int main()
{
char st1[30]="my name is";
char st2[10];
printf("输入你的名字:\n");
gets(st2)
strcat(st1);
}
strcpy
格式:
strcpy(字符数组名1,字符数组名2)
strcpy(字符数组名1,字符数组名2)
功能:
把字符数组2中的字符串拷贝到字符数组1中。穿结束标志"\0"也一同拷贝。
字符数组2也可以是一个字符串常量
把字符数组2中的字符串拷贝到字符数组1中。穿结束标志"\0"也一同拷贝。
字符数组2也可以是一个字符串常量
例:
#include<stdio/h>
main()
{
char st1[15],str2[]="c language";
strcpy(st1,st2);
puts(st1);
printf("\n");
}
字符数组1应该有足够的长度
#include<stdio/h>
main()
{
char st1[15],str2[]="c language";
strcpy(st1,st2);
puts(st1);
printf("\n");
}
字符数组1应该有足够的长度
说明:
可以用strcpy()函数将字符串2中前面若干个字符复制到字符数组1中去
可以用strcpy()函数将字符串2中前面若干个字符复制到字符数组1中去
strupr()
格式:
strupr(字符串)
strupr(字符串)
功能:
将字符串中小写字母转换成大写字母
将字符串中小写字母转换成大写字母
数组注意问题
引用数组应该用[]
数组元素可以使用最大下标
int i,a[10]={1};
for(i=1i<10;i++)
printf("%d",a[i]);
int i,a[10]={1};
for(i=1i<10;i++)
printf("%d",a[i]);
二维数组和多维数组的定义 和引用
int a[4][5]
int a[4][5]
用scanf函数向字符数组输入数组,不能加&
char a[20];
scanf("%s",a)
用scanf函数向数值型数组输入数据,要加&
char a[20];
scanf("%s",a)
用scanf函数向数值型数组输入数据,要加&
误以为数组名代表数组全部元素
int a[4]={1,3,5,7},b[4];
b=a; 这是错误的
int a[4]={1,3,5,7},b[4];
b=a; 这是错误的
字符数组的初始化和赋值
char str[10]="china" 这是正确的
char str[4];str="china" 这是错误的
char str[10]="china" 这是正确的
char str[4];str="china" 这是错误的
混淆字符和字符串的表现形式
char sex;
sex="m";
这是错误的,m是字符串,后面还有\0
char sex;
sex="m";
这是错误的,m是字符串,后面还有\0
数组的应用
数组的排序
选择法排序
冒泡法
数组中元素的插入和删除
查找
顺序查找
求二维数组的鞍点
按行求出各行最大的元素位置,某行最大元素与该元素所在列的所有元素比较,
判断是否是最小元素,是则是鞍点,否则不是
判断是否是最小元素,是则是鞍点,否则不是
函数
函数
函数就是功能
每一个函数用来实现一个特定的功能
函数的名字反映其代表的功能
int max(int x,int y) //求最大值
每一个函数用来实现一个特定的功能
函数的名字反映其代表的功能
int max(int x,int y) //求最大值
程序可由一个主函数和若干个其他函数构成
同一个函数调用可以被一个或多个函数调用任意多次(除了主函数)
例:
输出一下结果,用函数调用实现
****************
how do you do!
****************
输出一下结果,用函数调用实现
****************
how do you do!
****************
#include<stdio.h>
int main()
{
void print_star(); /*声明
void print_message(); 函数*/
print_star(); /*函数
print_message();
print_star(); 调用*/
return 0;
}
void print_starc() //函数定义
{
printf("****************\n";) //输出16个*
}
void_message()
{
printf("how do you do!\n";) //输出 how do you do!
}
int main()
{
void print_star(); /*声明
void print_message(); 函数*/
print_star(); /*函数
print_message();
print_star(); 调用*/
return 0;
}
void print_starc() //函数定义
{
printf("****************\n";) //输出16个*
}
void_message()
{
printf("how do you do!\n";) //输出 how do you do!
}
说明
一个c程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件
若干个源程序文件组成一个c程序
一个源程序文件可以为多个c程序共用
若干个源程序文件组成一个c程序
一个源程序文件可以为多个c程序共用
一个源程序文件由一个或多个函数以及其他有关内容组成
一个源程序文件是一个编译单位,在程序编译时以源程序文件为单位,进行编译的,不是以函数为单位
一个源程序文件是一个编译单位,在程序编译时以源程序文件为单位,进行编译的,不是以函数为单位
c程序的执行是从main函数开始,到main函数结束
所有函数都是平行的,即在定义时是分别进行的,是互相独立的
函数不能嵌套定义
函数间可以相互调用,但是不能调用main函数
main函数是被操作系统调用的
函数不能嵌套定义
函数间可以相互调用,但是不能调用main函数
main函数是被操作系统调用的
从声明角度看,函数有两种:
1.库函数
2.用户自己定义的函数
从函数的形式看,分两类:
1.无参函数
2.有参函数
1.库函数
2.用户自己定义的函数
从函数的形式看,分两类:
1.无参函数
2.有参函数
函数的定义
无参函数的定义
类型标识符 函数名() //函数头
{ //函数体
声明部分
语句
}
{ //函数体
声明部分
语句
}
void printsar()
{
printf("******\n";)
}
{
printf("******\n";)
}
有参函数的定义
类型标识符符 函数名(形式参数列表)
{
声明部分
语句
}
{
声明部分
语句
}
int max(int x,int y)
{
int z;
z=x>y?x:y;
return (z);
}
{
int z;
z=x>y?x:y;
return (z);
}
定义空函数
类型名 函数名()
{}
{}
例:
编写一个求阶乘的函数,求5!+6!+7!
编写一个求阶乘的函数,求5!+6!+7!
#include<stdio.h>
int main()
{
int fac(int n); // 函数的原型声明
int i,a,b,c;
a=fac(5):
b=fac(6);
c=fac(7);
printf("5!+6!+7!=%d\n",a+b+c);
}
int fac (int n) //函数的定义
{
int i,f=1;
for(i=1;i<n;i++)
f=f*i;
return f;
}
int main()
{
int fac(int n); // 函数的原型声明
int i,a,b,c;
a=fac(5):
b=fac(6);
c=fac(7);
printf("5!+6!+7!=%d\n",a+b+c);
}
int fac (int n) //函数的定义
{
int i,f=1;
for(i=1;i<n;i++)
f=f*i;
return f;
}
例:
求两个整数中的较大者
求两个整数中的较大者
#include<stdio.h>
int main()
{
int max(int x,int y); //函数的原型声明
int a,b;
scanf("%d,%d",&a,&b);
printf("%d是最大值i\n",max(a,b); //函数的调用
}
int max(int x,int y) //函数的定义
{
int m;
if(x>y)
m=x;
else
m=y;
return m;
}
int main()
{
int max(int x,int y); //函数的原型声明
int a,b;
scanf("%d,%d",&a,&b);
printf("%d是最大值i\n",max(a,b); //函数的调用
}
int max(int x,int y) //函数的定义
{
int m;
if(x>y)
m=x;
else
m=y;
return m;
}
函数的调用
函数调用的形式
函数名(实参表列)
函数名(实参表列)
如果调用无参函数,则“实参表列”可以没有,但是括号不能省略
如果实参表列包含多个实参,则各参数之间用逗号隔开。c=max(a,b)
如果实参表列包含多个实参,则各参数之间用逗号隔开。c=max(a,b)
三种函数调用形式
函数调用语句
把函数调用单独作为一个语句 如:print_star()
这是不能要求函数带回值,只要求函数完成一定的操作
这是不能要求函数带回值,只要求函数完成一定的操作
函数表达式
函数调用出现在另一个表达式中,如c=max(a,b);
这是要求函数带回一个确定的值以参加表达式的运算
这是要求函数带回一个确定的值以参加表达式的运算
函数参数
函数调用作为另一个函数调用时的实参,如m=max(a,max(b,c));
其中max(b,c)是一次函数调用,他的值作为max另一次调用的实参
其中max(b,c)是一次函数调用,他的值作为max另一次调用的实参
函数调用时的数据传递
在调用有参函数时,主调函数和被调函数之间有数据传递关系
定义函数时函数 名后面的变量名称为“形式参数”
主调函数调用一个函数时,函数名后面函数称为实际参数
实际参数可以是常量、变量或表达式
定义函数时函数 名后面的变量名称为“形式参数”
主调函数调用一个函数时,函数名后面函数称为实际参数
实际参数可以是常量、变量或表达式
函数调用的过程
在定义函数中指定的形参,在未出现函数调用时,他们并不占内存中的存储单元。
在发生函数调用时,函数max的形参被临时分配内存单元
在发生函数调用时,函数max的形参被临时分配内存单元
实参与形参的类型应相同或赋值兼容
C语言规定,实参变量对形参变量的数据传递是值传递(即单向传递),只由实参传给形参,
不能由形参传回实参。在内存中,实参单元与形参单元是不同的单元
不能由形参传回实参。在内存中,实参单元与形参单元是不同的单元
调用结束,形参单元被释放
实参单元维持原值,没有改变
如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值
实参单元维持原值,没有改变
如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值
函数的返回值
通过函数调用使主调函数能得到一个确定的值,这就是函数值(函数返回值)
函数的返回值是通过函数中的return语句获得的
一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一个就起作用
return 表达式 ;或return (表达式);
return后面的值可以是一个表达式 return(x>y?x:y);
如果被调用函数中没有return语句,说明没有希望得到函数值。
为了明确表示“不常回值”,可以用void定义函数无类型,此时函数中不能有return语句
函数值的类型和函数定义中函数的类型应保持一致。如果函数值的类型和return语句中表达式的值不一致,以函数类型为准
不加类型说明的函数,自动按整型处理
一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一个就起作用
return 表达式 ;或return (表达式);
return后面的值可以是一个表达式 return(x>y?x:y);
如果被调用函数中没有return语句,说明没有希望得到函数值。
为了明确表示“不常回值”,可以用void定义函数无类型,此时函数中不能有return语句
函数值的类型和函数定义中函数的类型应保持一致。如果函数值的类型和return语句中表达式的值不一致,以函数类型为准
不加类型说明的函数,自动按整型处理
被调用函数的声明和函数原型声明
一个函数调用另一个函数应具备以下条件:
1.被调研函数必须是已经定义的函数
2.如果用库函数,应该在本文件开头加上#include指令
3.如果使用自己定义的函数,而该函数的位置在调用它的函数后面,应该声明
1.被调研函数必须是已经定义的函数
2.如果用库函数,应该在本文件开头加上#include指令
3.如果使用自己定义的函数,而该函数的位置在调用它的函数后面,应该声明
函数的嵌套与递归
函数的嵌套与递归
C语言的函数定义是相互平行的,独立的
即函数不能嵌套定义,但可以嵌套定义函数
即调用一个函数的过程中,可以调用另一个函数
即函数不能嵌套定义,但可以嵌套定义函数
即调用一个函数的过程中,可以调用另一个函数
函数的递归调用
在调用一个函数的过程中,又出现直接或间接地调用该函数本身,称为函数的递归调用
数组作为函数参数
数组元素作为函数参数
数组元素就是变量,他与普通变量并无区别。
因此它作为函数实参使用与普通变量时完全相同的,在发生函数调用时,
把作为实参的数组元素的值传递给形参,实现单向的值传送
因此它作为函数实参使用与普通变量时完全相同的,在发生函数调用时,
把作为实参的数组元素的值传递给形参,实现单向的值传送
数组名做函数参数
用数组名做函数实参时,向形参传递的是数组首元素的地址
说明:
用数组名与数组元素做函数参数不同点
用数组名与数组元素做函数参数不同点
1.用数组元素作为实参时,对数组元素的处理是按普通元素对待的。
用数组名做函数参数时,这要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组声明
用数组名做函数参数时,这要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组声明
2.在函数调用时发生的值传递是把实参变量的值赋予形参变量。
在用数组名作函数参数时,不是进行值得传送,而是把实参数组的首地址回赋予形参数组
在用数组名作函数参数时,不是进行值得传送,而是把实参数组的首地址回赋予形参数组
用多维数组名作函数参数
多维数组元素与一维数组一样,可以看做一个变量,所以在调用函数时可以作为实参,进行值得传递
用多维数组作为函数参数传递的是数组首元素的地址,要求形参是相同类型的同维数组。
这里,形参是二维数组时,第二维的大小(长度)必须指明,而第一维的大小(长度)随便
int array[3][10] 或 int array[][10]
这里,形参是二维数组时,第二维的大小(长度)必须指明,而第一维的大小(长度)随便
int array[3][10] 或 int array[][10]
字符数组名做函数参数
用字符数组名做函数参数传递得到是数组首元素的地址
变量的作用域
变量的作用域
在程序中能对变量进行存取操作的范围称为变量的作用域
变量分为局部变量和全局变量
变量分为局部变量和全局变量
C语言
C语言的特点
语言简洁,紧凑,使用方便灵活。32个关键字,9种控制语句,程序形式自由。
丰富的运算符和数据类型,具有现代语言的各种数据结构。
具有结构化的控制语句,是完全模块化和结构化的语言。
能直接访问物理地址进行位操作,可以直接对硬件进行操作。
程序可移植性好(与汇编语言相比)。
C语言允许使用的两种注释方式
// :单行注释
/* ......*/:多行注释
C语言程序的结构特点
一个源程序文件包括
预处理指令:#include<stdio.h>
函数定义:每个函数用来实现一定的功能
函数是C程序的主要组成部分
一个c程序是由一个或多个函数组成的
必须包含一个main函数(只能有一个)
程序总是从main函数开始执行,到main函数结束
C语言规定,在一个源程序中,main函数的位置可以任意
一个函数包括两个部分
函数首部
函数体
c程序对计算机的操作由C语句完成
c程序书写格式是比较自由的。
为清晰可见,习惯上每行只写一个语句。
数据声明和语句最后必须有分号。
C语言本身不提供输入输出语句。
程序应当包含注释,增加可读性。
C语言一行写不下时可以跨行写,但要分两种情况
预处理一行写不下时
把一个预处理指示写成多行时要用“\”换行,因为根据定义,一条预处理指示只能由一个逻辑代码组成
正常程序一行写不下时
把c代码写成多行则不必使用续航符(在任意空白处换行)
算法
一个程序主要包括:对数据的描述(数据结构),对操作的描述(要求计算机进行操作的步骤,也是算法)两方面的信息
什么是算法:算法是为了解决问题而执行的一系列步骤
计算机算法分为两大类
数值运算法:求数值解
非数值运算法:用于事务管理
算法的特性
有穷性:一个算法应该包括有限的操作步骤,而不能无线
确定性:算法中的每一个步骤都是确定的
有零个或多个输入:所谓输入是指在执行算法时需要从外界取得必要的信息
有一个或多个输出:算法的目的数为了求解,“解”就是输出,没有输出的算法是无意义的
有效性:算法中的每一个步骤都应该有效执行,并得到确定结果
常量,变量
C语言的数据类型
基本类型
整型
实型(浮点型)
单精度型
双精度型
枚举型
构造类型
结构体类型
数组类型
共用体构造
空类型(void函数)
常量和符号常量
定义:在执行过程中,其值不发生改变的量称为常量,其值可改变的量称为变量
在程序中,常量是可以不经说明而直接引用的,而变量必须先定义后使用
直接常量(直面常量):可以直接从字面值看出来
整型常量:12/0、-3
实型常量:4.6、-1.23
字符常量'a'、'b'、'2'
符号常量:用标识符代表一个常量,称之为符号常量
符号常量一般格式为:
#define 标识符 常量
例如:#define PI 3.1415
#define 标识符 常量
例如:#define PI 3.1415
符号常量在使用之前必须先定义
符号常量后面不能用分号;
变量
定义:代表内存中具有特定属性的一个存储单位,用来存放数据,也就是该变量的值
程序编译连接执行时由系统给每个变量各分配内存地址
变量必须先定义后使用
标识符
定义:在C语言中用来对变量,符号常量,函数,数组等数据对象命名的有效符号序列统称为标识符
标识符命名规范
只能由字母、下划线、数字三种字符组成
第一个字符必须为字母下划线
不能使用C语言关键字
1、数据类型关键字(12个):
(1) char :声明字符型变量或函数 (2) double :声明双精度变量或函数
(3) enum :声明枚举类型 (4) float:声明浮点型变量或函数
(5) int: 声明整型变量或函数 (6) long :声明长整型变量或函数
(7) short :声明短整型变量或函数 (8) signed:声明有符号类型变量或函数
(9) struct:声明结构体变量或函数 (10) union:声明共用体(联合)数据类型
(11) unsigned:声明无符号类型变量或函数
(12) void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
(1) char :声明字符型变量或函数 (2) double :声明双精度变量或函数
(3) enum :声明枚举类型 (4) float:声明浮点型变量或函数
(5) int: 声明整型变量或函数 (6) long :声明长整型变量或函数
(7) short :声明短整型变量或函数 (8) signed:声明有符号类型变量或函数
(9) struct:声明结构体变量或函数 (10) union:声明共用体(联合)数据类型
(11) unsigned:声明无符号类型变量或函数
(12) void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
2、控制语句关键字(12个):
(1) for:一种循环语句 (2) do :循环语句的循环体
(3) while :循环语句的循环条件 (4) break:跳出当前循环
(5) continue:结束当前循环,开始下一轮循环
(6)if: 条件语句
(7)else :条件语句否定分支(与 if 连用)
(8)goto:无条件跳转语句 (9)switch :用于开关语句
(10)case:开关语句分支
(11)default:开关语句中的“其他”分支
(12)return :子程序返回语句(可以带参数,也看不带参数)
(1) for:一种循环语句 (2) do :循环语句的循环体
(3) while :循环语句的循环条件 (4) break:跳出当前循环
(5) continue:结束当前循环,开始下一轮循环
(6)if: 条件语句
(7)else :条件语句否定分支(与 if 连用)
(8)goto:无条件跳转语句 (9)switch :用于开关语句
(10)case:开关语句分支
(11)default:开关语句中的“其他”分支
(12)return :子程序返回语句(可以带参数,也看不带参数)
3、存储类型关键字(4个)
(1)auto :声明自动变量 一般不使用
(2)extern:声明变量是在其他文件正声明(也可以看做是引用变量)
(3)register:声明寄存器变量 (4)static :声明静态变量
(1)auto :声明自动变量 一般不使用
(2)extern:声明变量是在其他文件正声明(也可以看做是引用变量)
(3)register:声明寄存器变量 (4)static :声明静态变量
4、其它关键字(4个):
(1)const :声明只读变量 (2)sizeof:计算数据类型长度
(3)typedef:用以给数据类型取别名(当然还有其他作用
(4)volatile:说明变量在程序执行中可被隐含地改变
(1)const :声明只读变量 (2)sizeof:计算数据类型长度
(3)typedef:用以给数据类型取别名(当然还有其他作用
(4)volatile:说明变量在程序执行中可被隐含地改变
整型数据
整型常量的表示方法
十进制整数:123、0、-456
八进制整数:以<0>开头,0123
八进制不能有8
八进制不能有8
十六进制整数:以<0x>开头,0x123
整型变量
类型说明符 变量名标识符,变量名标识符,……
例如: int a,b,c;(a,b,c为整型变量)
long a,b,c;(a.b.c为长整型变量)
unsigned p,q;(p,q为无符号整型变量)
例如: int a,b,c;(a,b,c为整型变量)
long a,b,c;(a.b.c为长整型变量)
unsigned p,q;(p,q为无符号整型变量)
注意:
1.允许在一个类型说明符后,定义多个相同类型的变量。各变量名之间用逗号间隔。类型说明符与变量名之间至少用一个空格间隔。
2.最后一个变量名之后必须以“;”结尾。
3.变量定义必须放在变量使用之前。一般放在函数体的开头部分。
1.允许在一个类型说明符后,定义多个相同类型的变量。各变量名之间用逗号间隔。类型说明符与变量名之间至少用一个空格间隔。
2.最后一个变量名之后必须以“;”结尾。
3.变量定义必须放在变量使用之前。一般放在函数体的开头部分。
浮点型数据
实型常量的表示方法
实数,又称浮点数,十进制小数形式,如0..123.、123.、123.0、0.0
浮点型变量的分类
单精度float
有效数字:6
字节数:4
数的范围:0以及1.2*10的-38次方~3.4*10的38次方
有效数字:6
字节数:4
数的范围:0以及1.2*10的-38次方~3.4*10的38次方
双精度double
有效数字:15
字节数:8
数的范围:0以及2..3*10的-308次方~1.7*10的308次方
有效数字:15
字节数:8
数的范围:0以及2..3*10的-308次方~1.7*10的308次方
长双精度型long double
有效数字:19
字节数:16
数的范围:0以及3.4*10的-4932次方~1.1*10的4932次方
有效数字:19
字节数:16
数的范围:0以及3.4*10的-4932次方~1.1*10的4932次方
指数形式:数字+e(E)+整数
如123e3=123*10^3
如123e3=123*10^3
字母e(E)之前必须有数字,且e后面的指数必须是整数
字符型数据
字符常量
定义:用单引号''括起来的一个字符是字符型常量
只能包含一个字符
如'a','A','#','?','6'
如'a','A','#','?','6'
说明:
'A','a'是不同的字符常量
字符常量只能用单引号括起来,不能用双引号或其他括号
字符常量只能是单个字符,不能是字符串。
'A','a'是不同的字符常量
字符常量只能用单引号括起来,不能用双引号或其他括号
字符常量只能是单个字符,不能是字符串。
字符常量转义字符:以“\”开头的特殊字符
(转义字符只能使用小写字母,每个转义字符只能看做一个字符)
\n 换行,将当前位置移到下一行开头
\t 水平制表,跳到下一个tab位置,8位为一个tab位置
\b 退格,将当前位置移到前一列
\r 回车,将当前位置移到本行开头
\f 换页,将当前位置移到下一页开头
\\ 反斜杠字符"\",输出单个\
\' 单撇号字符,输出单个'
\" 双撇号字符,输出单个"
\ddd 1-3位八进制所代表的的字符
\xhh 1-2位十六进制所代表的的字符
\a 响铃
\v 垂直制表vt
\? 问号字符
\0 空字符
除了\r,其余转义字符的跳格,会取代原来屏幕上该位置显示的字符
(转义字符只能使用小写字母,每个转义字符只能看做一个字符)
\n 换行,将当前位置移到下一行开头
\t 水平制表,跳到下一个tab位置,8位为一个tab位置
\b 退格,将当前位置移到前一列
\r 回车,将当前位置移到本行开头
\f 换页,将当前位置移到下一页开头
\\ 反斜杠字符"\",输出单个\
\' 单撇号字符,输出单个'
\" 双撇号字符,输出单个"
\ddd 1-3位八进制所代表的的字符
\xhh 1-2位十六进制所代表的的字符
\a 响铃
\v 垂直制表vt
\? 问号字符
\0 空字符
除了\r,其余转义字符的跳格,会取代原来屏幕上该位置显示的字符
字符串常量
字符串常量是一对“双引号”括起来的字符序列
"how are you?" "china"A
"how are you?" "china"A
C规定:在每个字符串的结尾加一个“字符串结束标志\0”,以便系统据此判断字符串是否结束
在内存中字符串存储为:字符串+'\0'
书写时不必加'\0',系统会自动加上'\0'
书写时不必加'\0',系统会自动加上'\0'
字符变量
字符变量用来存放字符常量,但只能存放一个字符。
字符变量的定义形式如下
char c1,c2;
它表示c1和c2为字符型变量,各可以放一个字符
c1='a',c2='b';
字符变量的定义形式如下
char c1,c2;
它表示c1和c2为字符型变量,各可以放一个字符
c1='a',c2='b';
字符数据在内中的存储形式及其使用方法
将一个字符放到一个字符变量中,
在内存单元中,是将该字符的相应的ASCII代码放到存储单元中
在内存单元中,是将该字符的相应的ASCII代码放到存储单元中
函数strlen:计算给定字符串的长度,不包括“\0”在内
例如:表达式strlen("\x69\082\n")的值是1
运算符与表达式
变量赋初值
一般形式
类型说明符 变量1=值1,变量2=值2,……
类型说明符 变量1=值1,变量2=值2,……
int a=3; /* 指定a为整型变量,初始值为3 */
float f=3.14; /* 指定f为实型变量,初值为3.14*/
也可以使被定义的变量的一部分赋初值
int a,b,c=5;
如果对几个变量赋予初值为3,应写成
int a=3,b=3,c=3;
float f=3.14; /* 指定f为实型变量,初值为3.14*/
也可以使被定义的变量的一部分赋初值
int a,b,c=5;
如果对几个变量赋予初值为3,应写成
int a=3,b=3,c=3;
各类数值型数据间的混合运算
整数、实数、字符型数据可以混合运算
10+'a'+15-8768.123*'b'
10+'a'+15-8768.123*'b'
若参加运算的类型不同,则先转换成同一类型在进行计算
转换按数据长度增加的方向进行,以保证精度不降低
所有的浮点运算都是以双精度(double)进行的
char型和short型参与运算时,必须先转换为int型
在赋值运算中,赋值号两边的数据类型不同时,赋值号右边量的类型转换为左边量的类型
int a=3.2 a=3
int a=3.2 a=3
只要有double类型,运算结果也为double类型
算数运算符和算数表达式
C语言运算符简介
算数运算符 + - * / %
关系运算符 > < == >= <= !=
逻辑运算符 ! && ||
位运算符 << >> ~ | ^ &
赋值运算符 =及其扩展运算符
条件运算符 ? :
逗号运算符 ,
指针运算符 * &
长度运算符 sizeof
强制类型转换运算符 (类型)
分量运算符 . ->
下标运算符 [ ]
其他 如函数调用运算符( )
关系运算符 > < == >= <= !=
逻辑运算符 ! && ||
位运算符 << >> ~ | ^ &
赋值运算符 =及其扩展运算符
条件运算符 ? :
逗号运算符 ,
指针运算符 * &
长度运算符 sizeof
强制类型转换运算符 (类型)
分量运算符 . ->
下标运算符 [ ]
其他 如函数调用运算符( )
算数运算符和表达式
基本的算数运算符
+ - * /
+ - * /
两个整数相除的结果为整数
5/3结果为1,舍去小数部分
5/3结果为1,舍去小数部分
如果两个数有一个小数,结果为小数
5.0/2=2.5
5.0/2=2.5
除数或被除数中有一个为负值,舍入方向不固定
%运算符:称为求余运算符
%两侧均为整型数据
7%4的值为3
7%4的值为3
对于求余运算,运算结果与第一个数的符号相同
一个变量a能被3整除,则写成a%3==0
算数表达式和运算符的优先级与结合性
强制类型转换运算符
含义:用来将一个算数表达式的值转换成所需类型
定义格式
(类型名)(表达式)
(类型名)(表达式)
int i;
float j;
j=10.01;
i=(int)j;
把j强制转换成整型赋给i
float j;
j=10.01;
i=(int)j;
把j强制转换成整型赋给i
注意:
无论是强制转换或是自动转换,都只是为了本次运算的需要而改变量的值
进行临时转换,而不改变数据说明时对该变量定义的类型
无论是强制转换或是自动转换,都只是为了本次运算的需要而改变量的值
进行临时转换,而不改变数据说明时对该变量定义的类型
自增自减运算
定义格式
++a,--a
a++,a--
含义 a=a+1
a=a-1
++a,--a
a++,a--
含义 a=a+1
a=a-1
++a,--a 在使用之前,先使a的值加1/减1(先加后用)
a++,a-- 在使用之后,使a的值加1/减1(先用后加)
a++,a-- 在使用之后,使a的值加1/减1(先用后加)
a++与++a的区别
a++在使用a之后,使a的值加1,因此执行完a++之后,整个表达式的值为a,而a的值变为a++
++a在使用a之前,使a的值加1,因此执行完++a后,整个表达式的和a的值均变为a+1
a++在使用a之后,使a的值加1,因此执行完a++之后,整个表达式的值为a,而a的值变为a++
++a在使用a之前,使a的值加1,因此执行完++a后,整个表达式的和a的值均变为a+1
注意事项:
自增自减运算只能用于变量,不能用于常量和表达式。如5++,(a+b)++都不合法
++和--的结合方向是自右向左
自增自减运算只能用于变量,不能用于常量和表达式。如5++,(a+b)++都不合法
++和--的结合方向是自右向左
赋值运算符和赋值表达式
赋值运算符 “=”
a=3
a=3
类型转换
如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时要进行类型转换
int a;
a=6.3
a的值为6
a=6.3
a的值为6
将实型(浮点型)数据赋给整型变量时,舍弃小数部分
将整型数据赋给单双精度变量时,数字不变,但以实数形式存储到变量中
将一个double型数据赋给一个float型变量时,截取前面的7位有效数字,存放到float变量的存储单元中
字符型数据赋给整型变量时,由于字符只能占一个字节,而整型变量为四个字节,因此将字符数据(8位)放到整型变量低8位中
将一个int,short,long型数据赋给char型变量时,只将其低八位原封不动的送到char型变量(即截断)
复合的赋值运算符
在赋值运算符“=”之前加上其他运算符
一般形式为:变量 双目运算符=表达式
它等效于 变量=变量 运算符 表达式
它等效于 变量=变量 运算符 表达式
a+=3等价于a=a+3
x*=y+8等价于 x=x*(x+8)
x%=3等价于 x=x%3
x*=y+8等价于 x=x*(x+8)
x%=3等价于 x=x%3
赋值表达式
定义:由赋值运算符将一个变量和一个表达式连接起来的式子
一般形式:
<变量> <赋值运算符> <表达式>
<变量> <赋值运算符> <表达式>
注意:不能把一个表达式赋给另一个表达式,只能赋给一个变量
逗号运算符和逗号表达式
C语言提供一种特殊的运算符——逗号运算符
用它将两个表达式连接起来
用它将两个表达式连接起来
一般形式:
表达式1,表达式2
扩展:表达式1,表达式2,……,表达式n
表达式1,表达式2
扩展:表达式1,表达式2,……,表达式n
求解过程:根据左结合性,分别求n个表达式的值,并以表达式n的值作为整个逗号表达式的值
最右边的值是整个表达式的值
最右边的值是整个表达式的值
a=3*5,a*4 表达式的值为60
(a=3*5,a*4),a+5 表达式的值是20
(a=3*5,a*4),a+5 表达式的值是20
C语言常用的数学函数
abs
功能:求整数x的绝对值
说明:计算|x|,当x不为负时返回x,否则返回-x
fabs
功能:求浮点数x的绝对值
说明:计算|x|,当x不为负时返回x,否则返回-x
ceil
功能:求不小于x 的最小整数
说明:返回x的上限
如74.12的上限是75
-74..12的上限为-74,返回值为float类型
如74.12的上限是75
-74..12的上限为-74,返回值为float类型
floor
求不大于x 的最大整数
说明:返回x的下限
如74.12的下限是74
-74..12的下限为-75,返回值为float类型
如74.12的下限是74
-74..12的下限为-75,返回值为float类型
pow
功能:计算x 的y次幂
说明:x应大于0,返回幂指数的结果
sqrt
功能:计算x的平方根
说明:x应该大于0
sin
计算x(弧度表示)的正弦值
说明:x的值域为[-1.0,1.0]
格式输出输入
C语句的分类
表达式语句
一般形式:表达式;
例:x=y+z;i++
函数调用语句
一般形式:函数名(实际参数表)
例:printf("C Program");
复合语句
把多个语句用{}括起来组成一个语句
例:{
x=y+z;a=b+c;
print("%d%d",x,a);
}
x=y+z;a=b+c;
print("%d%d",x,a);
}
控制语句
条件判断语句:if switch
循环执行语句:do while,while,for
转向语句:break,goto,continue,return
空语句
只有分号";"组成的语句,什么也不执行,在程序中可做空循环体
赋值语句
一般形式:变量=表达式
例 int a;
a=5;
例 int a;
a=5;
说明
在变量说明中给变量赋初值和赋值语句的区别
1. int a=6,b=6,c=6; /*变量赋初值*/
2. int a,b,c; /*变量的定义*/
a=6,b=6,c=6; /*赋值语句*/
3. int a,b,c; /*变量的定义*/
a=b=c=6; /*赋值语句的嵌套*/
1.2.3之间等价
2. int a,b,c; /*变量的定义*/
a=6,b=6,c=6; /*赋值语句*/
3. int a,b,c; /*变量的定义*/
a=b=c=6; /*赋值语句的嵌套*/
1.2.3之间等价
赋值表达式和赋值语句的区别
赋值表达式可以包括在其他表达式之中,赋值语句不能
if((x>y;)>0) z=x; 错
if((x>y)>0) z=x; 对
if((x>y)>0) z=x; 对
数据输入输出的概念及实现
c语句本身不提供输入输出语句
输入输出操作是由C标准函数库的函数来实现的
printf();
scanf();
getchar();
putchar();
scanf();
getchar();
putchar();
在使用输入输出函数时,要在程序文件的开头用预编译指令
#include<stdio.h>
字符数据的输入输出
putchar函数(字符输出函数)
向终端输出一个字符
一般形式:
putchar(字符变量)
putchar(字符变量)
getchar函数(字符输入函数)
从键盘上输入一个字符,当输入多个字符时,只取第一个
一般形式:
getchar()
getchar()
格式输出——printf函数
printf函数
作用:按照指定的输出格式,向终端输出若干个任意类型的数据
一般格式:
printf(格式控制,输出表列)
如printf("%d,%c\n",i,c);
printf(格式控制,输出表列)
如printf("%d,%c\n",i,c);
格式控制
用双引号括起来的字符串,它包括两种信息
格式说明,由"%"和格式字符组成,
如%d,%f。
如%d,%f。
格式字符
整数的格式输出
d格式符:输出十进制整数
%d: 按整型数据的实际长度输出
%md: m为指定字段的输出宽度
如果数据的位数小于m,则左端补空格
如果数据的位数大于m,则按实际位数输出
如 printf("%4d",a);
如果数据的位数小于m,则左端补空格
如果数据的位数大于m,则按实际位数输出
如 printf("%4d",a);
%ld: 输出长整型数据
long int a=135790;
printf("%ld",a);
long int a=135790;
printf("%ld",a);
%o格式符: 以八进制输出无符号整数
%x格式符:以十六进制输出无符号整数
%u格式符: 输出十进制无符号(unsigned)整数
字符的格式输出
c格式符:用来输出一个字符
s格式符:用来输出一个字符串
%s:按字符串的实际长度输出
%ms:m为指定输出字段的宽度
如果字符串长度小于m,左边补空格
如果字符串长度大于m,按实际长度输出
如果字符串长度小于m,左边补空格
如果字符串长度大于m,按实际长度输出
%m.ns:输出占m列,只取字符串左端n个字符,
输出在右侧,左补空格
输出在右侧,左补空格
%-m..ns:输出在左侧,右补空格。
如果n>m,则m自动取n值,输出n个字符
如果n>m,则m自动取n值,输出n个字符
实数的格式输出
单精度floal有效位:6位
双精度double有效位:15位
双精度double有效位:15位
f格式符:用来输出实数,以小数形式输出
%f:系统自动指定宽度,整数部分全部输出,小数部分输出6位
%m.nf:输出占m列,n为小数位,输出在右侧,左端补空格
%-m.nf:输出在左侧,右端补空格
如果m小于(整数位数+n),则正常输出,小数部分输出n位
如果m小于(整数位数+n),则正常输出,小数部分输出n位
e格式符:以指数形式输出实数
%e:系统自动指定宽度,共13位,小数部分占6位,指数占5位
%m.ne输出占m列,n为小数位,输出在右侧,左补空格
%-m.nf:输出在左侧,右端补空格
如果m小于(整数位数+n),则正常输出,小数部分输出n位
如果m小于(整数位数+n),则正常输出,小数部分输出n位
%me:没有指定小数位,则小数位6位
g格式符:
用来输出实数,输出格式为f格式或e格式,
系统会根据数据占宽度m大小,自动选择
占宽度较小的某种格式输出,g格式不输出小数点后无意义的0
用来输出实数,输出格式为f格式或e格式,
系统会根据数据占宽度m大小,自动选择
占宽度较小的某种格式输出,g格式不输出小数点后无意义的0
格式字符归纳
普通字符,需要原样输出的字符
(一般都是说明性文字和逗号,空格等)
(一般都是说明性文字和逗号,空格等)
输出列表
需要输出的一些数据,可以使变量,也可以是表达式
格式输入——scanf函数
scanf函数
一般形式
scanf(格式控制,地址列表)
地址列表可以是变量的地址(加&)或字符串的首地址
scanf(格式控制,地址列表)
地址列表可以是变量的地址(加&)或字符串的首地址
格式声明
以%开始,以一个格式字符结束,中间可以插入
附加的字符(如“,”)
附加的字符(如“,”)
格式字符归纳
&a声明
&是一个取地址运算符,&a是一个表达式,其功能是求变量的地址。
这个地址是编译系统在内存中给a变量分配的存储空间地址
这个地址是编译系统在内存中给a变量分配的存储空间地址
变量的值和变量的地址是两个不同的概念
变量的地址是C编译系统分配的
变量的地址和变量值关系如下
如a=567;a为变量名,567是变量的值
&a是变量a的起始地址1001。
变量的地址是C编译系统分配的
变量的地址和变量值关系如下
如a=567;a为变量名,567是变量的值
&a是变量a的起始地址1001。
使用scanf函数应注意的问题
scanf函数没有精度控制
scanf函数中要求给出变量地址,而不是变量名
若格式控制中没有非格式字符做输入数据之间的间隔,则可以空格,tab,回车做间隔
如果有非格式字符,则在输入时,在对应位置上要输入这些字符
如果有非格式字符,则在输入时,在对应位置上要输入这些字符
在输入字符数据时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符
例:scanf("%c%c%c",&c1,&c2,&c3);
输入a_b_c
输出a_b_
因为把'a'赋给c1,把_赋给c2,'b'赋给c3,因为空格是有效字符
输入a_b_c
输出a_b_
因为把'a'赋给c1,把_赋给c2,'b'赋给c3,因为空格是有效字符
如果%后面有一个“*”附加说明符,表示跳过他指定数列
例:scanf("%2d_%*3d_%d",&a,&b);
输入12_345_67
系统将12赋给a,%*3d表示读入3位整数,但不会赋给任何变量,跳过345,将67赋给b
输入12_345_67
系统将12赋给a,%*3d表示读入3位整数,但不会赋给任何变量,跳过345,将67赋给b
关系运算符和关系表达式
关系运算符
C语言提供6中关系运算符
1. < 小于
2. > 大于
3. <= 小于等于
4.>= 大于等于
5.== 等于
6.!= 不等于
1、2、3优先级相同(高)
4、5、6优先级相同(低)
1. < 小于
2. > 大于
3. <= 小于等于
4.>= 大于等于
5.== 等于
6.!= 不等于
1、2、3优先级相同(高)
4、5、6优先级相同(低)
算数运算符(+ - * / %)、关系运算符(> < >= <= == !=)、
赋值运算符(=)的优先级比较
赋值运算符(=)的优先级比较
算数运算符 高
关系运算符 ↓
赋值运算符 低
关系运算符 ↓
赋值运算符 低
关系表达式(左结合性)
定义:用关系运算符将两个表达式连接起来的式子
一般形式:
表达式 关系运算符 表达式
表达式可以是
算数表达式 a+b>c-d
逻辑表达式 、关系表达式 (a>b)>(c-d)
赋值表达式 (a=3)>(b=5)
字符表达式 'a'+1>c
表达式 关系运算符 表达式
表达式可以是
算数表达式 a+b>c-d
逻辑表达式 、关系表达式 (a>b)>(c-d)
赋值表达式 (a=3)>(b=5)
字符表达式 'a'+1>c
关系表达式的值是一个逻辑值,即真或假
C语言编译系统在表示逻辑运算结果时,1代表真,0代表假
但是在判断一个量是否为“真”时,以“0代表假”,以非零的数值代表真
但是在判断一个量是否为“真”时,以“0代表假”,以非零的数值代表真
逻辑运算符和逻辑表达式
逻辑运算符
1. && 逻辑与
2. || 逻辑或
3 ! 逻辑非
1、2是双目运算符,3是单目运算符
优先级: !→&& →||
2. || 逻辑或
3 ! 逻辑非
1、2是双目运算符,3是单目运算符
优先级: !→&& →||
a&&b 只有a,b都为真,则a&&b都为真
a||b 只要a,b有一个为真a||b为真
!a 若a为真,则!a为假
a||b 只要a,b有一个为真a||b为真
!a 若a为真,则!a为假
如a=7,b=8,c=9,a1=-7,求下列的值
a>b&&b>c 0
a+a1||b+a1 1
a>b||c>b 1
!a &&! b 0
! a|| b 1
a>b&&b>c 0
a+a1||b+a1 1
a>b||c>b 1
!a &&! b 0
! a|| b 1
逻辑运算符、算数运算符、关系运算符优先级
! 非 高
算数运算符 ↓
关系运算符 ↓
&&和|| ↓
赋值运算符 低
! 非 高
算数运算符 ↓
关系运算符 ↓
&&和|| ↓
赋值运算符 低
逻辑表达式
一般形式:
表达式 逻辑运算符 表达式
表达式 逻辑运算符 表达式
运算规则:
只有在必须执行下一个表达式才能求解时,才求解该表达式
(并不是所有的表达式都被求解)
只有在必须执行下一个表达式才能求解时,才求解该表达式
(并不是所有的表达式都被求解)
对于逻辑与(&&)运算,如果第一个操作数被判定为假,
系统不再判定或求解第二个操作数
系统不再判定或求解第二个操作数
对于逻辑或(||)运算,如果第一个操作数被判定为为真,
系统不再判定或求解第二个操作数
系统不再判定或求解第二个操作数
选择结构(if、switch)
if语句
if语句的作用:
用来判定所给的条件是否满足
并且判定的结果(真或假)决定执行给出的两种操作之一
并且判定的结果(真或假)决定执行给出的两种操作之一
if语句有三种基本形式
if
例题:输入两个数a,b判断并输出其中较大的数
main()
{
int a,b,max;
printf("输入两个数\n");
scanf("%d%d",&a,&b);
max=a;
if(max<b) max=b:
printf("max=%d",max);
}
main()
{
int a,b,max;
printf("输入两个数\n");
scanf("%d%d",&a,&b);
max=a;
if(max<b) max=b:
printf("max=%d",max);
}
if-else
例题:输入两个数a,b判断并输出其中较大的数
main()
{
int a,b,max;
printf("输入两个数\n");
scanf("%d%d",&a,&b);
if(a>b)
printf("max=%d\n",a);
else
printf("max=%d\n",b);
}
main()
{
int a,b,max;
printf("输入两个数\n");
scanf("%d%d",&a,&b);
if(a>b)
printf("max=%d\n",a);
else
printf("max=%d\n",b);
}
if-else-if
if(表达式1) 如果表达式1为真,执行语句1;
语句1; 如果表达式2为真,执行语句2;
if(表达式2) .
语句2; .
. .
. .
. .
if(表达式n) 如果表达式n为真,执行语句n;
语句n; 否则执行语句m。
else
语句m;
语句1; 如果表达式2为真,执行语句2;
if(表达式2) .
语句2; .
. .
. .
. .
if(表达式n) 如果表达式n为真,执行语句n;
语句n; 否则执行语句m。
else
语句m;
例题:已知百分之成绩mark,显示对应等级成绩
90-100优秀 80-89良好 70-79中等
60-69及格 <60不及格
90-100优秀 80-89良好 70-79中等
60-69及格 <60不及格
void main()
{
int mark:
scanf("%d",&mark);
if(mark)<60
printf("不及格\n");
if(mark)<69
printf("及格\n");
if(mark)<79
printf("中等\n");
if(mark)<89
printf("良好\n");
if(mark)<100
printf("优秀\n");
else
printf("输入错误\n");
}
注意:
写这种多分支语句时,应该从小于小的,
大于打大的开始写
{
int mark:
scanf("%d",&mark);
if(mark)<60
printf("不及格\n");
if(mark)<69
printf("及格\n");
if(mark)<79
printf("中等\n");
if(mark)<89
printf("良好\n");
if(mark)<100
printf("优秀\n");
else
printf("输入错误\n");
}
注意:
写这种多分支语句时,应该从小于小的,
大于打大的开始写
if语句中应该注意的问题
该表达式通常是逻辑表达式或关系表达式,但也可以是其他表达式,甚至也可以是一个变量
if(a=5) if(b)
if(a=5) if(b)
在if语句中,条件判断表达式,必须用括号括起来,在语句之后必须加分号
if(a>b)
max=a;
if(a>b)
max=a;
在if语句的三种形式中,所有的语句应为单个语句,如果现在满足条件时执行一组(多个)语句,
则必须把这一组语句用{}括起来组成一个复合语句。但要注意在}后不能再加分号。
if(a>b) {a++,b++}
else {a=0,b=0;}
则必须把这一组语句用{}括起来组成一个复合语句。但要注意在}后不能再加分号。
if(a>b) {a++,b++}
else {a=0,b=0;}
例题:输入两个实数,按代数值从小到大的顺序输出这两个数
解题思路:如果a>b,交换a,b如果a<b,不用交换
int main()
{
float a,b,t;
scanf("%a,%b",&a&b);
if(a>b)
{
t=a;
a=b;
b=t;
}
printf("%52f,%5.2f\n",a,b)
return 0;
}
解题思路:如果a>b,交换a,b如果a<b,不用交换
int main()
{
float a,b,t;
scanf("%a,%b",&a&b);
if(a>b)
{
t=a;
a=b;
b=t;
}
printf("%52f,%5.2f\n",a,b)
return 0;
}
if语句的嵌套
在if语句中又包含一个或多个if语句,称为if语句的嵌套
if()
if()
语句1;
else
语句2;
else
if()
语句3;
else
语句4;
else总是与它前面最近的没有配对的if配对
if()
语句1;
else
语句2;
else
if()
语句3;
else
语句4;
else总是与它前面最近的没有配对的if配对
例题:比较两个数的大小关系
main ()
{
int a,b;
printf("输入两个数:\n");
scanf("%d,%d",&a&b);
if(a!=b)
if(a>b)
printf("a>b\n");
else
printf("a<b\n");
else
printf("a=b\n");
}
main ()
{
int a,b;
printf("输入两个数:\n");
scanf("%d,%d",&a&b);
if(a!=b)
if(a>b)
printf("a>b\n");
else
printf("a<b\n");
else
printf("a=b\n");
}
条件运算符
?
格式:
表达式1?表达式2:表达式3
如果表达式1为真,执行表达式2;否则执行表达式3
表达式1?表达式2:表达式3
如果表达式1为真,执行表达式2;否则执行表达式3
例:
if(a>b) 等价于 max=(a>b)?a:b;
max=a;
else
max=b;
if(a>b) 等价于 max=(a>b)?a:b;
max=a;
else
max=b;
结合性:
自右向左
自右向左
switch语句——实现多分支选择结构
一般形式:
switch(表达式) 表达式可以使整数类型(包括字符型)
{
case 常量表达式1:语句1;break;
case 常量表达式2:语句2;break;
case 常量表达式3:语句3;break;
……
case 常量表达式n:语句n;break;
default:语句n+1;
}
{
case 常量表达式1:语句1;break;
case 常量表达式2:语句2;break;
case 常量表达式3:语句3;break;
……
case 常量表达式n:语句n;break;
default:语句n+1;
}
说明
在case后的常量表达式值不能相同,否则会出现错误
在case后,允许有多个语句,可以不用{}括起来,没有语句时,什么也不做,直到遇到后面的break。
case和default子句的先后顺序可以变动,而不会影响程序执行的结果
default子句可以省略不用
case后不能出现多个变量,不能出现变量及有关运算符
例题:按考试成绩等级输出百分制分数段,
A等85分以上,B等70-84分,C等60-69分,D等60分以下
由键盘输入成绩等级
A等85分以上,B等70-84分,C等60-69分,D等60分以下
由键盘输入成绩等级
void main()
{
char mark;
scanf("%c",&mark);
switch(mark)
{
case A:printf("85分以上\n");break;
case B:printf("70-74分\n");break;
case C:printf("60-69分\n");break;
case D:printf("60分以下\n");break;
default:printf("输入错误\n");break;
}
}
{
char mark;
scanf("%c",&mark);
switch(mark)
{
case A:printf("85分以上\n");break;
case B:printf("70-74分\n");break;
case C:printf("60-69分\n");break;
case D:printf("60分以下\n");break;
default:printf("输入错误\n");break;
}
}
选择结构综合举例
写一个程序,判断是否是闰年
用变量leap代表是否是闰年的信息
若是闰年,令leap=1,非闰年,leap=0
最后判断leap是否为1(真),若是输出闰年信息
用变量leap代表是否是闰年的信息
若是闰年,令leap=1,非闰年,leap=0
最后判断leap是否为1(真),若是输出闰年信息
#include<stdio.h>
void main()
{
int year leap;
printf("请输入一个年份\n");
scanf("%d",&year);
if(year%4==0)
if(year%100==0)
if(year%400==0)
else leap=0;
else leap=1;
else
leap=0;
if(leap)
printf("%d是闰年",year);
else
printf("%d不是闰年",year);
printf("a leap year \n");
}
void main()
{
int year leap;
printf("请输入一个年份\n");
scanf("%d",&year);
if(year%4==0)
if(year%100==0)
if(year%400==0)
else leap=0;
else leap=1;
else
leap=0;
if(leap)
printf("%d是闰年",year);
else
printf("%d不是闰年",year);
printf("a leap year \n");
}
0 条评论
下一页