【思路】:
① 有地方放输入的数字;
② 有办法输入数字;
③ 输入的数字能参与计算。
【代码】:
#include <stdio.h>
int main()
{
int price = 0; // 定义了整型变量price --- 变量是保存数据的地方;变量的名字是一种“标识符”
// 标识符只能由字母、数字和下划线组成,数字不能出现在第一个位置上
printf("请输入金额(元):");
scanf("%d", &price); // 注意price前面的 & ;
int change = 100 - price;
printf("找您%d元。\n", change);
return 0;
}
【Note:】
1、变量是保存数据的地方;变量的名字是一种“标识符”;
2、标识符只能由字母、数字和下划线组成,数字不能出现在第一个位置上;
1、作用:输入
2、eg.
scanf("%d",&price);
注意:
① scanf 中,price前面有一个&
;
② “%d",表明scanf要读取一个整数,交给后面的变量;
“%lf”,表示要读取一个浮点数;
③ 出现在scanf的格式字符串中的东西,是一定要输入的东西。
1、eg.主程序:
const int AMOUNT = 100;
int price = 0;
printf("请输入金额(元):");
scanf("%d", &price); // 注意price前面的 & ;
int change = AMOUNT - price;
printf("找您%d元。\n", change);
2、const 是一个修饰符,加在int 前。初始化后不能修改,即不能再赋值;
3、让用户输入变量 AMOUNT ,而不是使用固定的初始值
【主程序】:
int amount = 100;
int price = 0; // 定义了整型变量price --- 变量是保存数据的地方;变量的名字是一种“标识符”
// 标识符只能由字母、数字和下划线组成,数字不能出现在第一个位置上
printf("请输入金额(元):");
scanf("%d", &price); // 注意price前面的 & ;
printf("请输入票面:");
scanf("%d",&amount);
int change = amount - price;
printf("找您%d元。\n", change);
【运行结果】:
4、读入两个变量的值,将它们相加以后的结果输出:
【代码】:
int a;
int b;
printf("请输入两个整数:");
scanf("%d %d",&a,&b);
printf("%d + %d = %d\n",a,b,a+b);
1、两个整数的运算结果只能是整数;
eg. 10/3*3 = 9
2、浮点数
——小数点是浮动的;
3、当整型数和浮点数放在一起运算时,C会将整数转换为浮点数,再进行浮点数的运算;
【代码】:
#include <stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英尺7英寸:");
int foot;
int inch;
scanf("%d %d", &foot, &inch);
printf("身高是%f米。\n",
((foot + inch / 12.0) * 0.3048));
return 0;
}
#include<stdio.h>
int main(){
int foot,inch;
int cm;
float m,t;
scanf("%d",&cm);
m = cm/100.0;
// foot + inch / 12 = m/0.3048;
t = m/0.3048;
// foot = t的整数部分;
// inch = t的小数部分*12
foot = t;
inch = (t - foot)*12;
printf("%d %d",foot,inch);
return 0;
}
4、双精度浮点数 double
【代码】:
#include <stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英尺7英寸:");
double foot;
double inch;
scanf("%lf %lf", &foot, &inch); // lf 来表达输入的事 double 类型
printf("身高是%f米。\n",
((foot + inch / 12) * 0.3048));
return 0;
}
运行结果与上述相同。
1、整数 int :输入输出都用%d
;
printd("%d",...);
scanf("%d",...);
2、带小数点的数:
double
printf("%f",...);
scanf("lf",...);
【思路】:
1、程序中要有哪些变量,这些变量要怎么读入数据、表达数据;
2、有了数据以后,怎么去计算;
【代码】:
#include <stdio.h>
int main()
{
int hour1,minute1;
int hour2,minute2;
int t1,t2,t;
scanf("%d %d",&hour1,&minute1);
scanf("%d %d",&hour2,&minute2);
t1 = hour1 * 60 + minute1; // 转换成以分钟为单位
t2 = hour2 * 60 + minute2;
t = t2 - t1;
printf("时间差是%d小时%d分", t/60, t%60 ); // t/60 -- 小时部分, t%60 -- 分钟部分
return 0;
}
【思路】:
1、有什么样的变量来保存读进来的东西;
2、怎么计算;
【代码】:
#include <stdio.h>
int main()
{
int a,b;
double c;
scanf("%d %d",&a,&b);
c = (a + b) / 2.0;
printf("%d和%d的平均值=%lf\n",a,b,c);
return 0;
}
1、单目运算,只有一个算子。eg. -a;
2、单目运算符的优先级高于乘除:
eg.
a*-b; // 先算-b,再与a相乘;
3、相同优先级——从左到右→结合;
【例外】:单目运算符、赋值运算——从右向左结合;
4、【例题】:
10 + 9 * ((8 + 7) % 6) + 5 * 4 % 3 * 2 + 3 // 44
1 + 2 + (3 + 4) * ((5 * 6 % 7 / 8) - 9) * 10 //-627
5、嵌入式赋值:
int a = 6;
int b;
int c = 1 + (b=a);
缺点:不利于阅读;易产生错误;
6、举例:
result = a = b = c + 3; // 先算3+c,再赋给b,再赋给a,再赋给result;
result = (result = result * 2)*6*(result = 3+result); //最好不要用嵌入式赋值!!要拆开几个表达式
【程序】:
#include <stdio.h>
int main()
{
int a,b;
int c;
printf("请输入a与b的值:");
scanf("%d %d",&a,&b);
c = a;
a = b;
b = c;
printf("a=%d,b=%d\n",a,b);
return 0;
}
1、包括+=
、-=
、*=
、/=
、%=
。
2、eg.
total += 5; // total = total + 5
total *= sum + 12; // total = total * (sum + 12) --- 先把右侧算完,再与total计算
1、形式:++
;--
。是单目运算符。
2、如:
count ++; // count += 1 ;即 count = count + 1
a++; // a++的值是a加1以前的值
++a; //++a 的值是加了1以后的值
3、案例程序
#include <stdio.h>
int main()
{
int a=10;
printf("a++ =%d\n",a++);
printf("a = %d\n",a);
printf("++a = %d\n",++a);
printf("a = %d\n",a);
return 0;
}
(1)题目内容:
逆序的三位数:
程序每次读入一个正三位数,然后输出逆序的数字。注意,当输入的数字含有结尾的0时,输出不应带有前导的0。比如输入700,输出应该是7。
提示:用%10可以得到个位数,用/100可以得到百位数…。将这样得到的三个数字合起来:百位100+十位10+个位,就得到了结果。
【代码】:
#include <stdio.h>
int main()
{
int a;
printf("请输入一个三位数:");
scanf("%d",&a);
printf("逆序数 = %d\n", (a%10)*100+(((a-(a/100)*100)/10)*10)+a/100);
// 得到十位数的方法也可以是:① a%100,再/10 ;或 ② a/10 再 %10
return 0;
}
#include <stdio.h>
int main()
{
int hour1,minute1;
int hour2,minute2;
int ih,im;
scanf("%d %d",&hour1,&minute1);
scanf("%d %d",&hour2,&minute2);
ih = hour2 - hour1;
im = minute2 - minute1;
if(im<0){
im = 60+im;
ih --;
}
printf("时间差是%d小时%d分", ih, im );
return 0;
}
== 相等
!= 不相等
> 大于
>= 大于或等于
< 小于
<= 小于或等于
Note:
关系运算的结果只有2种:关系成立,结果是1;否则,是0.
1、所有的关系运算符的优先级比算术运算的低,但比赋值运算的高。
printf("%d", 7>=3+4 ); // 运行结果 = 1
2、判断是否相等的==
和!=
的优先级比其他的低,而连续的关系运算是【从左到右】结合的。
printf("%d", 6>5>4 ); // 运行结果 = 0
printf("%d", 5>3 == 6>4 ); // 运行结果 = 1
printf("%d", a == b == 6 ); //从左到右
#include <stdio.h>
int main()
{
// 初始化
int price = 0;
int bill = 0;
//读入金额和票面
printf("请输入金额:");
scanf("%d", &price);
printf("请输入票面:");
scanf("%d", &bill);
// 计算找零
if(bill>=price)
printf("应该找您:%d\n", bill - price);
else
printf("你的钱不够\n");
return 0;
}
#include <stdio.h>
int main()
{
const double RATE = 8.25; // 每小时的薪水
const int STANDARD = 40; // 一周的标准工作时间
double pay = 0.0;
int hours;
printf("请输入工作的小时数: ");
scanf("%d", &hours);
printf("\n");
if (hours > STANDARD)
pay = STANDARD * RATE + (hours-STANDARD) * (RATE * 1.5);
else
pay = hours * RATE;
printf("应付工资: %f\n", pay);
return 0;
}
#include <stdio.h>
int main()
{
const int PASS=60;
int score;
printf("请输入成绩: ");
scanf("%d", &score);
printf("你输入的成绩是%d.\n", score);
if ( score < PASS )
printf("很遗憾,这个成绩没有及格。");
else {
printf("祝贺你,这个成绩及格了。");
printf("再见\n");
}
return 0;
}
#include<stdio.h>
int main()
{
int x;
int n = 1;
scanf("%d",&x);
if(x>999)
n = 4;
else if (x > 99)
n = 3;
else if(n > 9)
n = 2;
else
n = 1;
printf("%d\n",n);
return 0;
}
#include<stdio.h>
int main()
{
int x;
int n = 0;
scanf("%d",&x);
n++;
x /= 10;
while (x > 0){
n++ ;
x /= 10;
}
printf("%d\n",n);
return 0;
}
【Note】:
程序中, ++n; x/=10;不能全写到while循环语句中。因为x = 0 时,n应该 = 1。
do
{
<循环体语句>
}while(<循环条件>);
【note】:
1、无论条件满不满足,do-while一定会做一遍;而while在条件不满足时,什么都不做。
#include<stdio.h>
int main()
{
int x;
int n = 0;
scanf("%d",&x);
do
{
x /= 10;
n++ ;
} while(x > 0);
printf("%d\n",n);
return 0;
}
#include<stdio.h>
int main()
{
int n;
int fact = 1;
int i = 1;
scanf("%d",&n);
while(i <= n){
fact *= i;
i++;
}
printf("%d!=%d\n",n,fact);
return 0;
}
#include<stdio.h>
int main()
{
int n;
int fact = 1;
int i = 1;
scanf("%d",&n);
/* 从 1 乘到 n */
//for(i=1; i<=n; i++ ){ // ① 初始条件;② 循环条件;③ 增加步长
// fact *= i;
//}
for(i=n; i>1; i--){ // 从 n 乘到 1
fact *= i;
}
printf("%d!=%d\n",n,fact);
return 0;
}
for 语句也可写成如下,但只有C99编译能使用;
for( int i=1; i<=n; i++ ){
fact *= i;
}
【note】:
for 语句中的每个表达式都是可以省略的;但是分号不能省略!而
for(;条件;) == while(条件)
for
;do_while
;while
;头文件:
#include<stdbool.h>
之后就可以使用bool 和 true 、false
!
逻辑非;&&
逻辑与;||
逻辑或;! > && > ||
!age < 20; // 单目运算符的优先级高于双目运算符,故 !age 只会 = 0 或1;一定 < 20.
count = (count > 20)?count-10:count
// 条件?条件满足时的值:条件不满足时的值
右边
的表达式的值作为它的结果。for
中使用 for ( i=0,j=10; i
#include<stdio.h>
#include<stdbool.h>
int main(){
int a,b,c,max;
scanf("%d %d %d",&a,&b,&c);
if(a>b){
if(a>c)
max = a;
else
max = c;
}
else{
if(b>c)
max = b;
else
max = c;
}
printf("The max is %d\n",max);
return 0;
}
【Note】:
else
的匹配; int f;
if(x < 0){
f = -1;
}else if(x == 0){
f = 0;
}else{
f = x * 2;
}
#include<stdio.h>
int main(){
int type;
scanf("%d",&type);
if(type == 1)
printf("你好");
else if(type == 2)
printf("早上好");
else if(type == 3)
printf("晚上好");
else if(type == 4)
printf("再见");
else
printf("啊,什么呀?");
return 0;
}
#include<stdio.h>
int main(){
int type;
scanf("%d",&type);
switch (type){
case 1: // type == 1 时
printf("你好");
break;
case 2:
printf("早上好");
break;
case 3:
printf("晚上好");
break;
case 4:
printf("再见");
break;
default:
printf("啊,什么呀?");
break;
}
return 0;
}
【Note】:
switch(控制表达式){
case 常量:
语句
……
case 常量:
语句
……
default:
语句
……
}
int
的结果;break
才会跳出;#include<stdio.h>
/* 计算log 以 2 为底,x 的对数*/
int main(){
int x,t;
int ret = 0;
scanf("%d",&x);
t = x;
while( t > 1 ){
t /= 2;
ret ++;
}
printf("log2 of %d is %d.\n", x, ret);
return 0;
}
【要求】:输入一系列正整数,最后输入 -1 表示输入结束,然后计算这些数字的平均数,输出输入的数字的个数和平均数。
【思路】:
#include<stdio.h>
/* 计算平均数 */
int main(){
int number;
int sum = 0;
int count = 0;
scanf("%d",&number);
while(number != -1){
sum += number;
count ++;
scanf("%d",&number);
}
/* do{
scanf("%d",&number);
if(number != -1){
sum += number;
count++; // count 表明从程序中读入了多少个数据;
}
}while (number != -1);
*/
printf("输入的%d个数的平均数 = %f\n", count, 1.0*sum / count);
return 0;
}
【需求】:计算机想一个数,让用户来猜。用户每输入一个数据,就告诉他大了还是小了,直到用户猜中为止。最后还要告诉他猜了多少次。
【思路】:
【代码】:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/* 猜数游戏 */
int main(){
srand(time(0));
int number = rand()%100+1; // 每次 召唤 rand() 就得到一个随机的整数;
// x % n 的结果是 [0,n-1] 的一个整数;
int a = 0;
int count = 0;
printf("我已经想好了一个 1-100 之间的数。\n");
do{
printf("请猜这个 1-100 之间的数:");
scanf("%d",&a);
count ++;
if (a > number){
printf("你猜的数大了。");
}else if(a < number){
printf("你猜的数小了。");
}
}while (a != number);
printf("太好了,你用了%d次就猜到了答案。\n", count);
return 0;
}
【Note】:
x % n
的结果是 [0,n-1] 的一个整数;rand()
就得到一个随机的整数;【思路】:
%10
的操作,就可的到 个位数;/10
的操作,就去掉了个位数【代码】:
#include<stdio.h>
/* 整数求逆 */
int main(){
int x,t;
int digit;
int ret = 0; // 初始时结果为0
/* 此时若输入为 700,则输出为 7 */
scanf("%d",&x);
t = x;
while(x > 0){
digit = x%10;
// printf("%d\n",digit);
ret = ret *10 + digit;
printf("x=%d, digit=%d, ret=%d\n", x, digit, ret);
x /= 10;
}
printf("整数%d的逆=%d。\n", t,ret);
return 0;
}
/* 此时若输入为 700,则输出为 007 */
scanf("%d",&x);
t = x;
while(x > 0){
digit = x%10;
printf("%d",digit);
ret = ret *10 + digit;
//printf("x=%d, digit=%d, ret=%d\n", x, digit, ret);
x /= 10;
}
【需求】:读入一个数x,判断x是不是素数。
素数:只能被 1 和自己整除的数,不包括1.
【代码】:
#include<stdio.h>
/* 判断是否是素数 */
int main(){
int x;
int i;
int isPrime = 1; // isPrime = 1,则 x 是素数
scanf("%d",&x);
for (i=2; i<x; i++){
if( x % i == 0){ // 说明不是素数
isPrime = 0;
break; //break; --- 跳出循环 ; continue; --- 跳过这一轮循环,进入下一轮
}
}
if (isPrime == 1){
printf("是素数。\n");
} else {
printf("不是素数。\n");
}
return 0;
}
【Note】:
【或】:
/* 判断是否是素数 */
int main(){
int x;
int i;
// int isPrime = 1; // isPrime = 1,则 x 是素数
scanf("%d",&x);
for (i=2; i<x; i++){
if( x % i == 0){ // 说明不是素数
// isPrime = 0;
break; //break; --- 跳出循环 ; continue; --- 跳过这一轮循环,进入下一轮
}
}
// if (isPrime == 1){
if (i == x){
printf("是素数。\n");
} else {
printf("不是素数。\n");
}
【代码】:
#include<stdio.h>
/* 输出 1-100 的素数 */
int main(){
int x;
int i;
int isPrime = 1; // isPrime = 1,则 x 是素数
//scanf("%d",&x);
x = 6;
for (x=2; x<100; x++)
{
for (i=2; i<x; i++){
if( x % i == 0){ // 说明不是素数
isPrime = 0;
break; //break; --- 跳出循环 ; continue; --- 跳过这一轮循环,进入下一轮
}
}
if (isPrime == 1){
printf("%d ",x);
}
}
printf("\n");
return 0;
}
【代码1】:
#include<stdio.h>
/* 输出前50个素数 */
int main(){
int x;
int i;
int isPrime = 1; // isPrime = 1,则 x 是素数
int cnt = 0; // 计数器
//scanf("%d",&x);
x = 2;
// for (x=2; x<100; x++)
while (cnt < 50)
{
for (i=2; i<x; i++){
if( x % i == 0){ // 说明不是素数
isPrime = 0;
break; //break; --- 跳出循环 ; continue; --- 跳过这一轮循环,进入下一轮
}
}
if (isPrime == 1){
printf("%d ",x);
cnt++;
}
x++;
}
printf("\n");
return 0;
}
【代码2】:
// for (x=2; x<100; x++)
// while (cnt < 50)
for (x=2; cnt<50; x++)
{
for (i=2; i<x; i++){
if( x % i == 0){ // 说明不是素数
isPrime = 0;
break; //break; --- 跳出循环 ; continue; --- 跳过这一轮循环,进入下一轮
}
}
if (isPrime == 1){
printf("%d ",x);
cnt++;
}
// x++;
}
printf("\n");
break
#include<stdio.h>
/* 凑硬币 _ 用1角、2角、5角的硬币凑出10元以下的金额 */
int main()
{
int x;
int one,two,five;
int exit = 0;
scanf("%d",&x);
for(one=1; one<x*10; one++){ // 1角最多是 x*10个
for(two=1; two < x*10/2; two++){ // 2角最多是 x*10/2 个
for(five=1; five < x*10/5;five++){
if(one + two*2 + five*5 == x*10){
printf("可以用%d个1角+%d个2角+%d个5角得到%d元\n",one,two,five,x);
exit = 1;
break; /* 【接力 break】*/
}
}
if(exit) break; // 相当于 exit ==1;
}
if(exit) break;
}
return 0;
}
【Note】:
goto
语句#include<stdio.h>
/* 凑硬币 _ 用1角、2角、5角的硬币凑出10元以下的金额 */
int main()
{
int x;
int one,two,five;
int exit = 0;
scanf("%d",&x);
for(one=1; one<x*10; one++){ // 1角最多是 x*10个
for(two=1; two < x*10/2; two++){ // 2角最多是 x*10/2 个
for(five=1; five < x*10/5;five++){
if(one + two*2 + five*5 == x*10){
printf("可以用%d个1角+%d个2角+%d个5角得到%d元\n",one,two,five,x);
goto out;
}
}
}
}
out:
return 0;
}
【代码】:
#include<stdio.h>
/* 求前 n 项和 —— 1+1/2+1/3+…1/n */
int main()
{
int n;
int i;
double sum = 0.0;
scanf("%d",&n);
for (i=1; i<=n; i++){
sum += 1.0/i;
}
printf("f(%d)=%f\n",n,sum);
return 0;
}
#include<stdio.h>
/* 求前 n 项和 _f(n)=1-1/2+1/3-1/4+…+1/n */
int main()
{
int n;
int i;
double sum = 0.0;
int sign = 1;
scanf("%d",&n);
for (i=1; i<=n; i++){
sum += sign*1.0/i;
sign = -sign;
}
printf("f(%d)=%f\n",n,sum);
return 0;
}
【或】:直接把 sign 定义为 double 类型
主程序:
int n;
int i;
double sum = 0.0;
// int sign = 1;
double sign = 1.0;
scanf("%d",&n);
for (i=1; i<=n; i++){
sum += sign/i;
sign = -sign;
}
printf("f(%d)=%f\n",n,sum);
【思路】:
【代码】:
#include<stdio.h>
/* 求最大公约数 */
int main()
{
int a,b;
int min;
int ret;
int i;
scanf("%d %d",&a,&b);
if (a<b){
min = a;
}else {
min = b;
}
for (i=1;i<min;i++){ // 从 1 开始,到 a 和 b 的最小值
if (a%i == 0){ // a 能被 i 整除
if ( b%i == 0){ // b 能被 i 整除
ret = i; // 目前的公约数
}
}
}
printf("%d和%d的最大公约数是%d\n",a, b, ret);
return 0;
}
【思路】:
a b t // t—— 余数
12 18 12
18 12 6
12 6 0
6 0
【代码】:
#include<stdio.h>
/* 求最大公约数 */
int main()
{
int a,b;
int t;
scanf("%d %d",&a, &b);
while ( b!=0)
{
t = a%b;
a = b;
b = t;
printf("a=%d,b=%d,t=%d\n",a, b, t);
}
printf("gcd=%d.\n", a);
return 0;
}
【代码】:
#include<stdio.h>
/* 求最大公约数 —— 先逆序,再逆序,—— 只适用于末尾不是0的数*/
int main()
{
int x,d;
int t = 0;
scanf("%d",&x);
do{ /* 做【逆序】 */
d = x%10;
t = t*10 + d;
x /= 10; // x 右移一位
}while (x>0);
printf("x=%d,t=%d\n",x,t);
x = t;
do{ /* 【再逆序】 */
int d = x%10; // 得到最右边的一位
printf("%d",d);
if (x>=10){
printf(" "); // 使最后一轮时不输出空格
}
x /= 10; // x 右移一位
} while( x>0 );
printf("\n");
return 0;
}
【思路】:
eg.
x = 13425;
13425 / 10000 --> 1
13425 % 10000 --> 3425
10000 / 10 --> 1000
3425 / 1000 -->3
3425 % 1000 -->435
1000 / 10 -->100
425 / 100 -->4
425 % 100 -->25
100 /10 -->10
25 / 10 -->2
25 % 10 -->5
10 /10 -->1
5 / 1 -->5
5 % 1 -->5
1 /10 -->0
【代码】:
#include<stdio.h>
/* 求最大公约数 —— 正序输出 */
int main()
{
int d,x;
int mask = 1;
int t = 0;
int cnt = 0;
x = 13425;
t = x;
while (x > 9){ // 可以知道 x 的位数
x /= 10;
mask *= 10;
//cnt++;
}
printf("mask = %d\n",mask);
// mask = pow(10,cnt-1); // mask=10^(cnt-1)
do{
d = t / mask;
printf("%d",d);
if( mask >9 ){
printf(" ");
}
t %= mask;
mask /= 10;
// printf("x=%d,mask=%d,d=%d\n",x,mask,d);
}while ( mask >0 );
printf("\n");
return 0;
}
#include<stdio.h>
int main(){
int x;
double sum = 0;
int cnt = 0;
scanf("%d",&x); // 读入x
while(x != -1){
sum += x;
cnt ++;
scanf("%d",&x); // 读下一个数
}
if(cnt > 0 ){
printf("%f\n",sum / cnt);
}
return 0;
}
【思路】:
【如何记录很多的数】:
int num1,num2,num3……?
【数组】:
int number[100];
scanf("%d",&number[i]);
【代码】:
#include<stdio.h>
int main(){
int x;
double sum = 0;
int cnt = 0;
int number[100]; // 定义名为number的数组:数组里的每个单元都是 int;数组大小是100个。
scanf("%d",&x);
while(x != -1){
number[cnt] = x; // 对数组中的元素赋值
//
{
int i;
for ( i=0; i<=cnt; i++){
printf("%d\t",number[i]);
}
printf("\n");
}
//
sum += x;
cnt ++;
scanf("%d",&x);
}
if( cnt > 0 ){
// printf("%f\n", sum/cnt);
int i;
double average = sum/cnt;
for( i=0; i<cnt; i++ ){
if (number[i] > average) { // 使用数组中的元素
printf("%d",number[i]); // 遍历数组中的元素
}
}
}
return 0;
}
<类型> 变量名称[元素变量];
如: int grades[100];
double weight[20];
【Note】:
【数组的特点】:
[]
中的数字叫做 下标或索引,下标从0开始计数; int a[10];
// 10个单元: a[0],a[1],……,a[9]
a[2] = a[1] + 6; // 把a[1]的值读出来,加上6后,写入到a[2]中去;
【注意】:
有效的下标范围:
【案例程序】:
#include<stdio.h>
void f();
int main()
{
f();
return 0;
}
void f()
{
int a[10];
a[10] = 0; // a[10] 不是有效下标
}
问题:之前的程序是危险的,因为输入的数据可能超过100个。
优化:如果先让用户输入有多少数字要计算,可以用C99的新功能来实现。
【案例】:
写一个程序,输入数量不确定的 [0,9] 范围内的整数,统计每一种数字出现的次数,输入 -1 表示结束
【程序】:
#include<stdio.h>
int main(void)
{
const int number = 10; // 数组的大小
int x;
int count[number]; // count[i] 说明 i 这个数字出现了多少次
int i;
for( i=0; i<number; i++) { // 初始化数组
count[i] = 0;
}
scanf("%d",&x);
while ( x!= -1 ){
if ( x>=0 && x<=9 ){
count[x] ++; // 运算
}
scanf("%d",&x);
}
for ( i=0; i<number; i++){ // 遍历数组
printf("%d:%d\n", i, count[i] ); // i 这个数字出现了多少次
}
return 0;
}
#include<stdio.h>
int main(void)
{
int m,n;
int sum = 0;
int cnt = 0;
int i;
scanf("%d %d",&m,&n);
// m=10,n=31;
if(m==1) m=2;
for ( i=m; i<=n; i++){ //判断 i是不是素数
int isPrime = 1;
int k;
for(k=2; k<i-1;k++){
if(i%k == 0){
isPrime = 0;
break;
}
}
if(isPrime){
sum += i;
cnt++;
}
}
printf("%d %d\n",cnt,sum);
return 0;
}
#include<stdio.h>
int isPrime(int i ) // 定义的函数
{
int ret = 1;
int k;
for(k=2; k<i-1;k++){
if(i%k == 0){
ret = 0;
break;
}
}
return ret;
}
int main(void)
{
int m,n;
int sum = 0;
int cnt = 0;
int i;
scanf("%d %d",&m,&n);
// m=10,n=31;
if(m==1) m=2;
for ( i=m; i<=n; i++){ //判断 i是不是素数
if(isPrime(i)){
sum += i;
cnt++;
}
}
printf("%d %d\n",cnt,sum);
return 0;
}
#include<stdio.h>
int main()
{
int i;
int sum;
for( i=1,sum=0; i<=10; i++ ){
sum += i;
}
printf("%d到%d的和是%d\n",1,10,sum);
for( i=20,sum=0; i<=30; i++ ){
sum += i;
}
printf("%d到%d的和是%d\n",20,30,sum);
for( i=35,sum=0; i<=45; i++ ){
sum += i;
}
printf("%d到%d的和是%d\n",35,45,sum);
return 0;
}
注意:
代码复制 是程序质量不良的表现。
#include<stdio.h>
void sum(int begin, int end)
{
int i;
int sum = 0;
for( i=begin; i<=end; i++){
sum += i;
}
printf("%d到%d的和是%d\n",begin,end,sum);
}
int main()
{
sum(1,10);
sum(20,30);
sum(35,45);
return 0;
}
函数是一块代码,接收零个或多个参数,做一件事情,并返回零个或一个值。
void sum(int begin, int end)
—— 函数头{}
里面的 —— 函数体sum
—— 函数名void
—— 返回类型 void类型不返回结果()
里的 —— 参数表上述 素数求和 例子中:
int isPrime(int i ) // 定义的函数
{
int ret = 1;
int k;
for(k=2; k<i-1;k++){
if(i%k == 0){
ret = 0;
break;
}
}
return ret;
}
注意:
return
把那个结果交给调用它的地方。isPrime
会返回一个int
类型的结果int max(int a, int b)
{
int ret;
if (a>b){
ret = a;
}else (
ret = b;
)
return ret;
}
或者:(但最好用上面那种!)
int max(int a, int b)
{
// int ret;
if (a>b){
return a;
}else {
return b;
}
// return ret;
}
第二种虽然没有错,但是不符合单一出口的理念;
注意:
一旦遇到return
,就会 ①停止函数的执行,②并送回一个值;
两种写法:
return;
return 表达式;
一个函数里面可以出现多个return
语句
如:
#include<stdio.h>
int max(int a, int b)
{
int ret;
if (a>b){
ret = a;
}else {
ret = b;
}
return ret;
}
int main()
{
int a,b,c;
a = 5;
b = 6;
c = max(10,12);
c = max(a,b);
c = max(c, 23);
printf("%d\n",max(a,b));
return 0;
}
void 函数名(参数表);
return
return
return
#include<stdio.h>
void sum(int begin, int end); // 函数的【原型声明declaration】
int main()
{
sum(1,10); // 如没有 声明,会猜测 int sum(int,int)
sum(20,30);
sum(35,45);
return 0;
}
void sum(int begin, int end) // 函数 定义
{
int i;
int sum = 0;
for( i=begin; i<=end; i++){
sum += i;
}
printf("%d到%d的和是%d\n",begin,end,sum);
}
① 字面量[eg.10]、
② 变量[eg.a]、
③ 函数的返回值[eg.max(23,45)]、
④ 计算的结果[eg.23+45];
形式参数
”;调用函数时给的值,叫做“实际参数
”;形参
叫做参数
;把实参
叫做值
;本地变量
; 1.它可以是定义在 函数的块 内;
2.也可以定义在 语句的块 内
√ void f(void); // 在参数表里放了 void,明确的告诉编译器,这个函数不接收任何参数;
还是?
× void f(); // 在传统C中,它表示 f函数的参数表未知,并不表示没有参数
f(a,b) // 是标点
f((a,b)) // 是运算符
// 二者区别:到底是传了2个还是1个参数进去
int a[3][5]; // 通常理解为a是一个3行5列的矩阵
for ( i=0; i<3; i++){
for ( j=0; j<5; j++ ){
a[i][j] = i*j;
}
}
a[i][j]
表示第 i 行第 j 列上的单元a[i,j]
是一个表达式 int a[][5] = {
{0,1,2,3,4}, // 看做 5个int的数组,作为 a[0];
{2,3,4,5,6}, // 5个int的数组,作为a[1];
};
const int size = 3;
int board[size][size]; // 定义3×3 的棋盘
int i,j;
int numOfX;
int numOfO;
int result = -1; // -1:没人赢,1:X赢,0:O赢
// 读入矩阵
for ( i=0; i<size; i++ ){
for( j=0; j<size; j++){
scanf("%d", &board[i][j]); // 读入数组中的每一个元素
}
}
// 检查行
for ( i=0; i<size && result == -1; i++){
numOfO = numOfX =0; // 初始化最开始的数量为0
for( j=0; j<size; j++){ // 判断每一列
if( board[i][j] == 1){ //行号不变,列号从0到size
numOfX ++;
}else{
numOfO ++;
}
}
if( numOfO ==size ){
result =0;
}else if(numOfX == size){
result = 1;
}
}
// 检查列
for ( result == -1 ){
for( j=0; j<size && result == -1; j++){
numOfO = numOfX =0;
for( i=0; i<size; i++){
if( board[i][j] == 1){
numOfX ++;
}else{
numOfO ++;
}
}
}
if( numOfO ==size ){
result =0;
}else if(numOfX == size){
result = 1;
}
}
// 检查对角线。。。。
int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};
int a[13] = {2};
// 2 0 0 0 0 0 0 0 0 0 0 0 0
int a[10] = {
[0] = 2, [2] = 3, 6,
};
// a[0]=2; a[2]=3; a[3]=6; 其它的都为0;
sizeof
给出整个数组所占据的内容的大小,单位是字节; int a[] = {[1]=2,4,[5]=6}; // 0 2 4 0 0 6
printf("%lu\n",sizeof(a)); // 24
printf("%lu\n",sizeof(a[0])); // 4
sizeof(a)
/ sizeof(a[0])
;sizeof(a[0])
给出数组中单个元素的大小,于是相除就得到了数组的单元个数; int a[] = {[1]=2,4,[5]=6}; // 0 2 4 0 0 6
(False): int b[] = a; // 大错特错!!!!不行!!!!
int a[] = {[1]=2,4,[5]=6}; // 0 2 4 0 0 6
for ( i=0; i<length; i++) {
b[i] = a[i];
}
for
循环注意:
数组作为函数参数时,往往必须再用另一个参数来传入数组的大小!#include<stdio.h>
int search(int key, int a[], int len) // len 来表示数组有多大
{
int ret = -1;
for ( int i=0; i<len; i++)
{
if (key == a[i] )
{
ret = i;
break;
}
}
return ret;
}
int main()
{
int a[] = {1,3,4,5,12,14,23,6,9,45};
int r = search(12, a, sizeof(a)/sizeof(a[0]));
printf("%d\n", r);
return 0;
}
#include<stdio.h>
int amount[] = {1,5,10,25,50};
char *name[] = {"penny","nickel","dime","quarter","half-dollar"};
int search(int key, int a[], int len) // len 来表示数组有多大
{
int ret = -1;
for ( int i=0; i<len; i++)
{
if (key == a[i] )
{
ret = i;
break;
}
}
return ret;
}
int main()
{
int k = 25;
int r = search(k, amount, sizeof(amount)/sizeof(amount[0]));
if ( r > -1)
{
printf("%s\n",name[r]);
}
return 0;
}
#include<stdio.h>
int amount[] = {1,5,10,25,50};
char *name[] = {"penny","nickel","dime","quarter","half-dollar"};
struct {
int amount;
char *name;
} coins[] = {
{1,"penny"},
{5,"nickel"},
{10,"dime"},
{25,"quarter"},
{50,"half-dollar"}
};
int search(int key, int a[], int len) // len 来表示数组有多大
{
int ret = -1;
for ( int i=0; i<len; i++)
{
if (key == a[i] )
{
ret = i;
break;
}
}
return ret;
}
int main()
{
int k = 10;
// int r = search(k, amount, sizeof(amount)/sizeof(amount[0]));
for ( int i=0; i<sizeof(coins)/sizeof(coins[0]); i++ )
{
if ( k == coins[i].amount ){
printf("%s\n", coins[i].name);
break;
}
}
return 0;
}
【程序】:
#include<stdio.h>
int search(int key, int a[], int len) // len 来表示数组有多大
{
int ret = -1;
int left = 0;
int right = len-1;
while ( left < right )
{
int mid = (left+right)/2;
if( a[mid] == k )
{
ret = mid;
break;
} else if ( a[mid] > k)
{
right = mid-1;
} else{
left = mid+1;
}
}
return ret;
}
int main()
{
return 0;
}
【思路】:
swap a[maxid],a[len-1];
【代码】:
#include<stdio.h>
int max ( int a[], int len)
{
int maxid = 0;
for (int i=1; i<len ; i++ )
{
if( a[i]> a[maxid] )
{
maxid = i;
}
}
return maxid;
}
int main()
{
int a[] = {2,45,6,12,87,34,90,24,23,11,65};
int len = sizeof(a)/sizeof(a[0]);
for ( int i=len-1; i>0 ; i-- )
{
int maxid = max(a, i+1);
// swap a[maxid],a[len-1]
int t = a[maxid];
a[maxid] = a[i];
a[i] = t;
}
for (int i=0; i<len; i++)
{
printf("%d ",a[i]);
}
return 0;
}
sizeof
#include<stdio.h>
int main()
{
int a;
a = 6;
printf("sizeof(int) = %ld\n", sizeof(int)); // sizeof(int) = 4;int在内存中占4个字节,也就是32个bit
printf("sizeof(a) = %ld\n", sizeof(a)); // sizeof(a) = 4
printf("sizeof(double) = %ld\n", sizeof(double)); // sizeof(double) = 8
return 0;
}
&
scanf("%d",&i);
里的&
int i;
int* p = &i; // 表示p是一个指针,它指向的是一个 int,把i的地址交给了指针p
int* p,q; // 表示p是一个指针;q是一个普通的 int类型的变量
int *p,q; // 表示p是一个指针;q是一个普通的 int类型的变量
//【无论 * 是靠近 int 还是 p,都是一样的!!】
【无论 * 是靠近 int 还是 p,都是一样的!!】
void f(int *p);
f 函数要一个int的指针int i=0;f(&i);
#include<stdio.h>
void f(int *p);
void g(int k);
int main(void)
{
int i=6;
printf("&i=%p\n", &i);
f(&i);
g(i);
return 0;
}
void f(int *p)
{
printf(" p=%p\n", p);
}
void g(int k)
{
printf("k=%d\n", k); // k = 6
}
#include<stdio.h>
void f(int *p);
void g(int k);
int main(void)
{
int i=6;
printf("&i=%p\n", &i);
f(&i);
g(i);
return 0;
}
void f(int *p)
{
printf(" p=%p\n", p);
printf("*p=%d\n", *p); // 把 *p 看做一个整体,是int —— *p = 6;
*p = 26; // 此时,k = 26 —— 说明在经历了f函数的调用之后,i的值被改了
}
void g(int k)
{
printf("k=%d\n", k);
}
void minmax( int a[], int len, int *min, int *max)
// 上面的 int a[] ———— 指针!
// 也可以写成 int *a;
sizeof(a) == sizeof(int*);
[]
进行运算 int sum(int *ar, int n);
int sum(int *, int);
int sum(int ar[], int n);
int sum(int [], int);
[]
运算符可以对数组做,也可以对指针做:*
运算符可以对指针做,也可以对数组做: *a = 25;
int b[]; // 可以看做是 int * const b;
这是因为:
"
也是一个字符;#include<stdio.h>
int main()
{
char c;
char d;
c = 1;
d = '1';
if ( c==d ){ // 不相等
printf("相等\n");
} else{
printf("不相等\n");
}
printf("c=%d\n", c); // c=1
printf("d=%d\n", d); // d=49
return 0;
}
scanf("%c", &c); -->1
scanf("%d", &i); c=i; -->49
#include<stdio.h>
int main()
{
char c;
//scanf("%c",&c); // 输入: 1
//printf("c=%d\n", c); // c=49
//printf("c='%c'\n", c); // c='1'
int i;
scanf("%d",&i); // 输入: 1 or [49]
c = i;
printf("c=%d\n", c); // c=1 or [49]
printf("c='%c'\n", c); // c=' ' or ['1']
return 0;
}
scanf("%d %c",&i,&c);
scanf("%d%c",&i,&c);
#include<stdio.h>
int main()
{
char c;
int i;
scanf("%d %c",&i,&c);
printf("i=%d, c=%d, c='%c'\n", i, c, c);
return 0;
}
#include<stdio.h>
int main()
{
char c;
int i;
scanf("%d%c",&i,&c);
printf("i=%d, c=%d, c='%c'\n", i, c, c);
return 0;
}
a+'a'-'A'
可以把大写字母变成小写字母;a+'A'-'a'
小写字母变成大写!“/”
开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符; printf("请分别输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英尺7英寸:");
字符 | 意义 |
---|---|
\b |
回退一格 |
\t |
到下一个表格位 |
\n |
换行 |
\r |
回车 |
\" |
双引号 |
\' |
单引号 |
\\ |
反斜杠本身 |
\b
\t
char word[] = {'H','e','l','l','o','!'};
// 但 这不是C语言的字符串,因为不能用字符串的方式做计算!!
char word[] = {'H','e','l','l','o','!','\0'}; // 是字符串!
char *str = "hello";
char word[] = "hello";
char line[10] = "hello"; // 占据6个字节的line空间 —— 因为还有个结尾的0