上一篇文章:C语言程序设计概述+C语言简介+算法概述
C语言代码示范与讲解+C语言编程规范及基础语法+编程实战
一:代码示范集加讲解1.C语言第一个代码:打印"This is the first C program!"1.1解读1.2规范第一个代码2.输出输入代码示范集2.1输出一个整数2.2输出多个整数2.3输出多个小数2.4输入并输出多个整数和小数2.5一个非常重要的计算机计算误差,放到此博客最后讲3.代码示范:输入一个数求阶乘3.1思路描述3.2详细讲解+for循环语句的执行顺序3.3详细代码注释(scanf_s只在VS编译器中使用)二:C语言编程规范及基础语法1.C语言编程规范2.常量、变量命名规范3.函数命名规范4.标识符5.关键字6.C语言数据类型7.常量定义格式8.计算机中的储存单位9.整型数据10.整型变量11.浮点型数据12.浮点型变量13.字符型数据14.了解运算符与表达式15.自增自减的前置与后置16.关系运算符与关系表达式18.逻辑运算符与逻辑表达式19.复合赋值运算符20.运算符的优先级和结合性21.其他运算符(条件运算符、求字节运算符)22.数据类型转换22.1自动数据类型转换22.2赋值转换22.3强制类型转换22.4注意条件运算符中也会涉及到数据类型的自动转换23.C语言的基本语句24.数据的输出24.1格式化输出函数printf()24.1.1标志flag24.1.2输出宽度width24.1.3精度prec24.1.4长度24.1.5类型Type24.1.5.1类型指示符d24.1.5.2类型指示符f24.1.5.3类型指示符e24.1.5.4类型指示符g24.1.5.5类型指示符c24.1.5.6类型指示符s24.2单个字符的输出函数25.数据的输入25.1格式化输入函数scanf()25.2getchar()函数的格式26.小数的输入和输出的注意事项27.数据的存储28.while循环和do-while循环三:编程实战代码讲解(几个重要内容我直接放进代码中了)1.重组一个三位数Recombine A Three Digit Number2.常用的数学函数Common Mathematical Functions3.用if语句实现分段函数Calculating Piecewise Functions4.用科学计数法表示较大或较小的数5.输出华氏度转摄氏度转换表6.输入一个数求阶乘(for循环来实现)7.输入一个数判断奇偶性8.else-if进行四则运算9.任意给出三角形的三个边长,判断是否能够组成三角形10.判断输入的是不是英文字母11.英文大小写字母的转换12.判断闰年13.switch语句的四则运算14.判断成绩等级15.goto语句与continue语句16.使用格雷戈里公式求pi的近似值(while语句)18.用嵌套循环打印一个高度为n的等腰三角型19.用嵌套循环打印一个高度为n的倒三角20.统计一个整数的位数21.猜数游戏22.从输入的一批以负数结束的成绩中选出最高分,用do-while语句实现23.使用for循环嵌套计算1!+2!+3!+4!+... ...+100!24.使用子函数求1!+2!+3!+4!+... ...+100!25.逆序输出一个整数26.使用嵌套循环输出100以内的全部素数27.穷举法的板砖解决方案问题,第一版28.穷举法搬砖问题第二版29.利用子函数求100以内的全部素数30.利用子函数,利用格雷戈里公式求PI的近似值31.数字特征题31.1代码一31.2代码二:代码优化31.3代码三:31.4代码四31.5代码五31.6代码六32.局部变量与全局变量32.1局部变量32.2全局变量33.用函数实现财务现金记账。34.变量生存周期和静态局部变量34.1变量生存周期34.2变量存储的内存分布34.3静态变量35.输出1!~n!(全局变量法)36.while的妙用,统计输入的正整数中奇数和偶数的个数37.条件运算符的应用(三目运算符)38.强制数据类型转换的举例39.printf();函数的格式字符串的举例40.求二元一次方程的解40.1代码40.2调试41.爬楼梯问题,一次只能爬1阶或2阶,求爬到顶端共有多少种不同的方法,斐波那契数列42.二进制转十进制43.十进制转二进制44.二进制转换为十进制数值范围扩大45.一个重要的计算机计算误差案例下一篇文章
一:代码示范集加讲解
1.C语言第一个代码:打印"This is the first C program!"
/*This is the first C program!*/
#include //编译预处理命令
main() //主函数
{
printf("This is the first C program!\n"); //调用printf()函数打印要输出的语句
}
/*
解读:
第一行是注释,C语言中使用两个斜杠中间加两个星号进行注释,注释内容放在星号中间。也可以用双斜杠的形式进行单行注释,注释内容放在双斜杠后面,注意双斜杠只能进行单行注释。
双斜杠加星号可以进行多行注释
*/
1.1解读
执行的结果为:
This is the first C program!第一行是注释,C语言中使用两个斜杠中间加两个星号进行多行注释,注释内容放在两个星号中间。也可以用双斜杠的形式进行单行注释,注释内容放在双斜杠后面,注意双斜杠只能进行单行注释。双斜杠加星号可以进行多行注释。
编译器在编译的时候会自动跳过注释部分,只编译注释以外的代码部分。
注释的意义:在代码必要的地方进行注释,日后时间久了回过头来再看的时候,帮助我们理解代码;并且以后走上工作岗位,一个项目可能不是一个人在做,需要团队合作,想要让团队其他成员更好地理解自己的代码就需要适当的注释,提高团队的工作效率,所以要养成代码注释的好习惯。第二行是编译预处理命令,我们调用了printf()函数进行打印达到输出内容的目的,而printf()函数是在库文件中的,库文件中有很多函数,都是前人写好的函数,我们直接调用就行了。在调用printf()函数前,我们需要编译预处理命令把它包含进来,格式为 #include ,stdio.h是头文件。后缀.h是头文件的一个标志,字母h是英文单词head(头)的缩写。printf()函数是在库文件中的,而头文件的作用相当于一个导游。第三行main()是主函数,编译器在编译代码的时候都是从主函数开始编译的。后面的花括号括起来的内容为主函数的语句,称为主函数的函数体。C语言中的每条语句都要以分号结尾,如果缺少分号,系统会报错的。注意一定不能少了分号,这个是初学者经常犯的错误。且分号一定要是英文状态下的分号。第五行是调用printf()函数来进行语句的输出,把要输出的内容用双引号引起来。\n反斜杠n是转义字符,它的意思是回车换行。
1.2规范第一个代码
好了,我们的第一个C语言程序讲完了。但是代码书写不规范,现在我们再把它改一下,代码如下:
#include
int main(void)
{
printf("This is the first C program!\n");
return 0;
}
在第二行,我们加了一个int,这个是主函数的函数类型,函数类型与它的返回值有关,int是整型,当不写int时,默认为int整型。return 0;是函数返回值,因为它没有返回值,所以直接返回0,也可以省去,因为我们只是打印一句话。括号里面的是主函数的参数,因为这个主函数没有参数,所以我们用void(空),也可以直接省去。
对于初学者要注意编程规范,语法要规范。因为有些编译器对语法要求严格,不这样写会出错,有些编译器则不会要求这么严格。具体情况具体看待。
2.输出输入代码示范集
2.1输出一个整数
#include
int main()
{
int n
=3;
printf("%d",n
);
return 0;
}
执行的结果为:
3
变量与常量:变量在使用前必须要先定义,int n;就是定义一个变量n,int是变量的类型,n为变量名。所谓常量就是直接写一个数,比如a=3*b;这是一个算术表达式,表达式中的3就是一个常量,它是一个整型常量,*号的意思是乘,就是3乘b并把乘得的结果赋给变量a。如果我写成了a=3.0*b;此时常量为3.0,加上了小数点的常量默认为double型。int n=3;定义一个整型数据,并给他赋初始值为3printf("%d",n);引号里面的是要输出的内容,%d是要输出的整型数据,这个语句的意思是直接输出n的值。
2.2输出多个整数
#include
int main()
{
int a
,b
,c
,d
=3,e
=1;
a
=b
=c
=5;
printf("%d,%d,%d,%i,%i\n",a
,b
,c
,d
,e
);
return 0;
}
执行的结果为:
5,5,5,3,1int a,b,c,d=3,e=1;定义abcde五个变量,并给d赋初始值3,e赋初始值1。a=b=c=5;给abc三个变量赋值5。=为赋值符号,右结合性,所谓右结合性,即从右往左运算,左结合性反之。注意不能写成int a=b=c=5,d=3,e=1;printf("%d,%d,%d,%i,%i\n",a,b,c,d,e);这行代码的意思是按照abcde变量的顺序输出对应的变量值。注意:%d和%i都是整型的占位符
2.3输出多个小数
#include
int main()
{
float a
=3.14159;
double b
=5.324352,c
=343.324;
printf("%f,%f,%f",a
,b
,c
);
return 0;
}
执行的结果为:
3.141590,5. 324352,343. 324000float单精度浮点型数据,double双精度浮点型数据,都是小数点后六位,double取值范围更大一些
2.4输入并输出多个整数和小数
#include
int main()
{
int a
,b
;
float c
,d
;
double e
;
scanf("%d%i%f%f%lf",&a
,&b
,&c
,&d
,&e
);
printf("%d,%d,%f,%f,%f",a
,b
,c
,d
,e
);
return 0;
}
运行:
3(输入3按下回车,把它的值给a)
4(输入4按下回车,把它的值给b)
3.14(输入3.14按下回车,把它的值给c)
5.1234(输入5.1234按下回车,把它的值给d)
5.1234567(输入5.1234按下回车,把它的值给e)
3,4,3.14,5.123400,5.123456
scanf()函数的调用,scanf()函数是实现从键盘输入的一个函数,和printf()函数一样也包含在stdio.h头文件中。
2.5一个非常重要的计算机计算误差,放到此博客最后讲
请按照顺序看完后,最后再看这个计算机计算误差
3.代码示范:输入一个数求阶乘
//Enter A Number To Find The Factorial(输入一个数求阶乘)
#include
int factorial(int a
);
int main(void)
{
int n
;
scanf_s("%d", &n
);
printf("%d\n", factorial(n
));
return (0);
}
int factorial(int a
)
{
int i
, fact
= 1;
for (i
= 1; i
int i
, fact
= 1;
for (i
= 1; i
int n
;
scanf_s("%d", &n
);
printf("%d\n", factorial(n
));
return (0);
}
3.for循环
for循环格式:
for(语句一; 语句二; 语句三;)
{
循环体;
}
语句:
语句一是循环变量初始化,本例题中 i 为循环变量,赋初始值为1。
语句二,判断循环的终止条件。
语句三,改变循环变量i的值,设置循环步长。i++等价于i=i+1,这里的1为循环步长,如果是i=i+2,那么循环步长为2
语句的执行顺序:先执行语句一,再执行语句二,判断i的值是否满足语句二的循环终止条件,若满足循环终止条件,则结束循环;若不满足循环终止条件,则执行循环体语句,然后执行语句三,改变循环变量的值,再判断是否满足循环终止条件,以此往下类推,直到结束为止。
变量初始化这里的fact变量在执行循环前必须初始化,否则循环无法执行,很多初学者都容易犯这样的错误。例如:上面的代码fact在定义的时候就已经赋了初始值。建议初学者不要这样写,容易忘记给它赋初始值。建议循环变量的赋值放在循环外面单独一行或几行(循环变量多的时候一行赋一个)
花括号的妙用花括号要上下对齐,格式美观,提高可读性,避免代码过多,可读性下降,也不利于后期维护
3.3详细代码注释(scanf_s只在VS编译器中使用)
//Enter A Number To Find The Factorial(输入一个数求阶乘)
#include //编译预处理命令
int factorial(int n
); //这是一个子函数,调用前要提前声明
int main(void) //int可以省略,不写int默认为整型,void可以省略
{
int n
; //定义一个变量n
scanf_s("%d", &n
); //使用scanf()不会检查输入边界,可能造成数据溢出。scanf_s()会进行边界检查。
//scanf("%d",x); 指从键盘给x输入一个int整形数据;scanf("%f",x); 指从键盘给x输入一个float或double实型(即小数)数据
//printf("%d",x); 指按整型数据输出x中的值
//后缀_s更安全,传入一个和参数有关的大小值,避免引用到不安全(漏洞)黑掉系统。
//scanf("%s",&name,n); 整型n为name类型的大小,如果name是数组,那n就是该数组的大小
//注意scanf_s()函数只能在VS编译器中使用,是VS编译器对scanf()函数的一个特殊修改,标准C中并没有scanf_s函数,所以如果你使用的是其他编译器,要把scanf_s改为scanf
printf("%d\n", factorial(n
)); //这里调用了子函数,把子函数中的值输出
return (0); //返回值可以加括号,也可以不加括号,通常情况下是不加的,了解一下就行了
}
int factorial(int n
) //这里是子函数的具体内容,不写int默认为整型
{
int i
, fact
= 1; //这里是子函数中定义的变量
for (i
= 1; i
return PI
* r
* r
* h
;
}
解读:第一行宏定义,只在VS中使用,在其他编译器去掉第一行宏定义
8.计算机中的储存单位
最小的储存单位:bit,位
8bit=1byte(字节)
1024byte=1kb(千字节)
1024kb=1mb(兆字节)
1024mb=1gb(吉字节)
1024g=1tb(太字节)
往后还有很多更大的,这里不写了
9.整型数据
在C语言中整型常量可以以十进制、八进制、十六进制等形式出现
(1)十进制形式
(2)八进制形式:在数码前加数字0。例如:012、034等,其中012=1乘8的1次幂+2乘8的0次幂=10(十进制)
(3)十六进制形式:在数码前加0x(数字0和字母X或x)。例如:0x12、0x3e、0xff等,其中0x12=1乘16的1次幂+2乘16的0次幂=18(十进制)
十六进制的数码除了数字0到9外,还使用英文字母a到f(或A到F)表示10~15
10.整型变量
int占4个字节
short int 简称 short
long int 简称 long
singed 与 unsigned 有符号和无符号 与int、short、long自由组合
有符号就是有正负号,无符号就是没有正负号
整型变量有值域,具体值域要看编译器的种类
不同整型变量的值域是不同的,与其所占的字节数有关
定义整型变量:
int a,b;
short c=2,d;
unsigned long m,n;
整型变量值交换:
#include
main() //函数类型不写默认位整型
{
int a
,b
,c
;
printf("输入a和b的值:");
scanf("%d%d",&a
,&b
);
c
=a
;
a
=b
;
b
=c
;
printf("a=%d,b=%d\n",a
,b
); //单纯的打印输出功能的函数,可以没有返回值
//最后c的值为0
}
如果忘记了某个类型的变量占多少个字节,可以用sizeof()来求出该类型所占的字节数:

知道某个数据类型所占的字节数的情况下,我们就可以计算这个类型的变量所能存储的数据范围,例如:int型变量,刚刚在上面的图中我们已经求出了它占四个字节,一个字节等于8位,所以int型变量总共有32位,每个位上要么是1要么是0,最左端是符号位,1是正数,0是负数,因为int型是有符号的,所以去掉一个符号位,还剩31位,所以将这个31位最大的二进制数转换为十进制数:2^31-1=2147483647,2147483647就是有符号型int变量所能存储的数据的最大范围。
11.浮点型数据
十进制小数形式:由数字和小数点组成
实型常量不能用八进制或十六进制形式表示
小数点不能单独出现
一般对于非常大或非常小的数值,常用指数形式表示,其表现形式为:
十进制小数 e(或E) 十进制整数
13.5e-6 表示 0.0000135
0.3E3 表示 300
e或E的两边必须有数,且其后面必须为整数
12.浮点型变量
浮点型变量的储存形式
分为 符号||阶码||尾数 三个部分
符号决定正负号
阶码决定取值范围
尾数决定精度
单精度浮点型float 一般占4个字节(32位),从小数点后第7位开始就已经不准确了。

双精度浮点型double 一般占8个字节(64位),从小数点后第16位开始就已经不准确了。

使用浮点型变量的时候尽量使用double型的,float型的变量精度没有double的精度高,float型的容易出错
#include
main()
{
float a
,b
;
a
=1235578550.456789;
b
=a
+20;
printf("a=%f,b=%f\n",a
,b
);
}



13.字符型数据
字符型常量:一个字符型常量代表ASCII(美国信息交换标准代码)字符集中的一个字符,在程序中用单引号把一个字符括起来作为一个字符常量。例如:'A' '1' '?' 等
字符常量只能包含一个字符,例如'a'是正确的,而'ab'是错误的
字符常量在内存中占一个字节,作为整型常量来处理,对应的值是ASCII码值
单引号中大小写字母代表不同的字符常量,如'a'与'A'是不同的。大小写对应字母的ASCII值相差32
单引号'也是字符常量,不过单引号不能像其他字符一样简单地用单引号括起来,如‘'’的形式是错误的,而是使用转义字符来实现
字符'1'与数字1不是等价的,字符'1'的ASCII值为49
转义字符:
在C语言中定义了一些字母前加“\”来表示常见的那些不能显示的ASCII字符,如‘\0’ ‘\n’等,称为转义字符,如下表:

ASCII表链接
//转义字符的举例
#include
main()
{
printf(" ab\tde\rf\n");//\n为回车换行;\t为横向跳8个格;\r回到本行开头,输出f,覆盖一个空格;\\单反斜杠字符;\'为单引号;\"双引号
return 0; //\v为竖向跳格;\f为换页符;\b为退格符
}
程序运行结果为:
f ab de
说明:字符ab前有两个空格,故ab在第三列输出;在遇到\t时横向跳8个格,输出de;之后遇到\r执行一个回到本行开头的操作,本行开头输出的是空格,所以字符 f 覆盖了一个空格;最后的\n为回车换行操作
字符型变量
字符型变量的存储形式
字符变量用来存储字符型常量,一个变量只能存放一个字符,占一个字节,在内存中存储的是该字符的ASCII值得二进制形式,例如:字符‘A’在内存中得存储形式如图所示:(字符'A'的ASCII值为65,65的二进制数为1000001)
变量的定义:
字符变量的类型标识符为char,其定义形式为:
char 变量名1,变量名2,变量名3 ... ;
(字符型可参与数学运算,也可看成一种一字节的整型变量)
例如:
char c1,c2; //定义了两个字符型变量
字符型变量的特性:
每个字符型数据在内存中占一个字节,储存的是该字节的ASCII码,该ASCII码是一个无符号整数,其存储形式和整数的存储形式一样,所以C语言允许字符型数据与整型数据进行混合运算,运算时是使用字符的ASCII值来实现的。
所以,一个字符型数据,既可以以字符形式输出,也可以以整数形式输出
//字符型变量的输出
#include
main()
{
char c1
='A',c2
;
c2
=c1
+2;
printf("c1=%d,c2=%d\n",c1
,c2
);
printf("c1=%c,c2=%c\n",c1
,c2
);
}
这个程序运行的结果如下:
c1=65,c2=67
c1=A,c2=C
//大小写字母的转换
#include
main()
{
char c1
='A',c2
;
c2
=c1
+32;
printf("c1=%c,c2=%c\n",c1
,c2
);
}
运行结果:
c1=A,c2=a
扩展的ASCII码中含256个字符集,值在0~255之间,若超过了255,则将该数对256取余数。
字符串常量 用英文状态下的双引号引起来的内容,连同双引号一起为一个整体,这个整体就是字符串常量。
例如:"Hello world"
14.了解运算符与表达式
算术运算符+ -
*(乘)
/(除)
%(取余数运算符)
++(自增运算符)
--(自减运算符)
关系运算符(大于)
=(大于等于)
!=(判断是否不等于)
==(判断是否等于)
逻辑运算符! 逻辑非
&& 逻辑与
|| 逻辑或

位逻辑运算符

位运算符中只有~是单目运算符,其他皆为双目运算符
~ 按位求反运算符
将操作数按二进制数逐位求反,1变为0,0变为1
& 按位与运算符
例如:
84的二进制数01010100
59的二进制数00111011
按位求与后为00010000,即16的二进制数
求与规则:两个二进制数相同位数上的数字都为1,求与后该位上的数字为1,若不同或都为0,该位上的数字为0(参见二进制位逻辑运算真值表)二进制位逻辑运算真值表与逻辑运算真值表基本类似,真为1,假为0。注意按位异或是相同为0,不同为1
^ 按位异或运算符,异或规则和求与规则类似,参见二进制位逻辑运算符真值表
假设a=19,b=23,将a和b的值互换可执行一下语句
a^=b^=a^=b;
| 按位或运算符,规则参见二进制位逻辑运算符真值表
右移位
例如:
a>>b表示将a的二进制值右移b位,a
int sales
;
float tc
;
printf("please input sales\n");
scanf("%d",&sales
);
tc
=(sales
>20000?sales
*0.1(sales
>10000?sales
*0.8:sales
*0.5));
printf("tc=%f\n",tc
);
return 0;
}
逗号运算符,主要把变量分隔开求字节运算符
C语言中的求字节运算符sizeof()是一个单目运算符,作用是求得变量或某种数据类型在在内存中的字节数。
求字节运算符使用形式有三种:
sizeof 变量名
sizeof (变量名)
sizeof (类型名)
求字节运算的结果为整数
//求字节运算符的举例
#include
main()//不写int默认为整型
{
int a
,b
,e
,g
; //int是4个字节
float x
; //float是4个字节
double y
; //double是8个字节
short c
; //short是short int的简写,short是2个字节
b
= sizeof c
;
long int d
; //在这个编译器中long int是4个字节
e
= sizeof(d
);
long long f
; //long long是long long int的简写,它有8个字节//注意长整型数据输出时为了避免出错,最好以%ld的格式字符输出
g
= sizeof f
;
printf("%d,%d,%d,%d,%d,%d\n",sizeof a
,sizeof x
,sizeof(y
),b
,e
,g
);//sizeof后面可以加括号也可以不加括号
printf("%i,%i\n",sizeof(int),sizeof(float));//%i和%d是一样的
return 0;
}

22.数据类型转换
22.1自动数据类型转换
由精度低的向精度高的转换
例如:5+'a'/2.0+14.0/2;
计算步骤:
先进行优先级最高的运算,先将字符'a'转换为整型97
因为97为整型,2.0为double型,所以要将97转换为double型再运算
再计算14.0/2,14.0是一个带小数点的常量,默认为double型,结果为6.5
之后计算5+48.5+6.5,将5转换为double型
22.2赋值转换
整型数据赋值给float或double型变量,整型数据不变,但以浮点数形式存储到变量中。将float或double型数据赋给整型时,舍弃小数部分将字符型数据赋给整型变量,数值不变,将字符型变量的8个二进制位存入整型变量的低八位中。将整型数据赋给字符型变量,由于整型数据所占内存空间高于字符型,所以只将整型数据的低八位存入字符型变量中。float型数据转换为double型变量,数值不变,只在float型数据尾部加0以赋给double型变量。double型数据转换为float型变量,截取double型的前7位有效数字赋给float型变量。
22.3强制类型转换
(类型名)(表达式)
例如:
float a=2.7;int b;
b=(int)(a+2.4)%2;
如果写成了b=(int)a+2.4%2;,只是对a进行强制类型转换
强制类型转换时,只是得到所需类型的中间变量,原来变量的类型不会改变。
22.4注意条件运算符中也会涉及到数据类型的自动转换
三目的条件运算符,三个操作数中如果有一个是double型的,两个整型的,那么根据自动转换规则,由低级到高级转换,两个整形的会转换成double型的。例如:
int n;
(n>0)?2.9:1;
如果n等于10,那么表达式的值为2.9
如果n等于-10,那么表达式的值为1.0,即由整型的1转换为1.0
23.C语言的基本语句
空语句:直接一个分号。
作用一:用于延时,消耗CPU的计算时间
作用二:起到占位符的作用
(个人觉得其实没有什么多大的作用,延时和占位都算不上什么作用,在算法优化的时候经常避免延时和占内存。空语句知道就行了,不作为实际应用。)复合语句:多条语句用花括号括起来,当作一条语句。知道就行了,经常用的。
24.数据的输出
24.1格式化输出函数printf()
它的原型为:
int printf(char * format [,argument,…]);
功能:向系统指定的输出设备按指定的格式输入任意个任意类型的数据,并返回实际输出的字符数,若出错,将返回负数。
格式字符:以%为引导,后跟各种格式字符,用来指定输出项的输出格式,如类型、形式、长度、小数等
普通字符:原样输出
格式字符串:不同数据类型在输出时需要指定不同的输出格式,所使用的格式字符也就不同。格式字符串的一般形式为:
%[flag][width][.prec][F|N|h|l]Type
24.1.1标志flag
标志字符有“+”“-”“#”和空格四种,分别代表的含义为:
+:对于正数符号位输出为正号“+”,对于负数输出负号“-”
空格:对于正数符号位输出空格,对于负数输出负号“-”
-:输出时左对齐,右侧补空格
#:如果加在格式字符c、s、d、u前时,对输出结果无影响,只有加在代表输出八进制的类型字符o前时才有意义。
例如:
int x=12;
printf("%o",x);
将十进制的12转化为八进制输出,输出结果为14
例如:
int x=12;
printf("%#o",x);
将十进制的12以八进制的形式输出,输出结果为014,前面的0是八进制数的标志
24.1.2输出宽度width
用十进制整数来表示输出的最少位数。若实际的位数多于指定的宽度,则按实际位数输出。当实际的位数少于指定的位数,则补以空格或0
24.1.3精度prec
精度格式以.开头,后跟十进制整数
24.1.4长度
F|N|h|l表示指针是否是远指针或整数是否是长整数
F:表示远指针
N:表示近指针

h:短整型或单精度浮点数(这个并不实用,知道这么回事就可以了)

还是要注意一点,上面这个图片中,输出的是1.123457而不是1.123456,因为小数点后的第七位大于5,所以进1,如果小数点后第七位小于或等于5,则不会进1


l:长整型或双精度浮点数
24.1.5类型Type
常用的类型指示符有以下几种:
24.1.5.1类型指示符d
用来输出带符号的十进制整数形式。使用形式有三种:
%d或%i:按十进制整数的实际长度输出%md:按指定长度m输出十进制整数,如果实际数据的位数小于m,则左端补空格,若大于m,按实际位数输出。%ld:输出长整型数据24.1.5.2类型指示符f
整数部分全部输出,并输出6位小数部分
24.1.5.3类型指示符e
以指数的形式输出十进制数,输出的宽度为标准宽度13位,其中尾数部分中整数部分占1位,小数点占一位,小数部分占六位,e占一位,指数部分正负号占一位,指数占3位
以指数输出实数时,也可以使用宽度控制符%m.ne的形式,整个数宽度至少占m位,n为尾数部分的小数部分,不足在左端补空格,多出的按实际位数输出。
24.1.5.4类型指示符g
用来输出实数,可以根据实数的大小自动选择以小数形式f或指数形式e输出,选择的标准是输出时占宽度较小的一种,且不会输出无意义的0,如:123.400000,输出时为123.4
24.1.5.5类型指示符c
输出字符
24.1.5.6类型指示符s
原样输出一个字符串
例如:printf("%s","hello world");
%ms,以宽度m输出字符串,如果字符串长度小于m,在左端补空格(右对齐)%-ms,上面类似,只不过字符串长度小于m时,在右端补空格(左对齐)%m.ns,右对齐的形式输出字符串,只输出字符串的前n个字符%-m.ns,左对齐的形式输出字符串,只输出字符串的前n个字符总结:
%d和%i都是输出整数
%o转化为八进制形式输出
%u以无符号的十进制形式输出
%X或%x以十六进制的形式输出
%c输出单个字符
%s输出字符串
%f以小数的形式输出实数
%E或%e以指数的形式输出
%G或%g自动选择%f和%e中宽度最小的形式输出实数,且小数点后面无意义的0自动省去(著:如果想输出%,则需要连续两个%%)
#include
int main()
{
int a
=3;
printf("%i%%\n",a
);
}
输出结果为
3%
24.2单个字符的输出函数
C语言中printf()函数可以完成所有的输出操作,但如果要输出单个字符的话使用putchar()函数更为简单
函数原型:int putchar(int ch);
25.数据的输入
25.1格式化输入函数scanf()
原型:int scanf(char *format [,argument,…]);
(1)地址列表:地址列表是若干个变量地址的列表,可以是变量地址、字符数组名及指针变量等。两个地址之间用‘逗号进行分隔。变量首地址的表示方法:&变量名。其中&是地址运算符。scanf()函数执行时将输入的数据流按指定格式转换为数据,存入相对应的存储单元中。
例如:
scanf("%d%d",&a,&b);
(2)格式字符:
格式字符串以%引导,其形式为:
%[*][width][F|N|h|l]type
各部分介绍如下:
类型字符:
基本上和printf()中的一致,只有float和double之间的区别,float是%f,而double是%lf,注意是字母l和字母f,而不是数字1和f。宽度指示符width是一个十进制整数的形式,表示该输入项最多可接收的字符个数,也就是说,读取输入数据中相应的n位,按需要的位数赋给相应的变量,多余的部分被舍弃。但读取过程中如遇到空格、tab或其他不可转换的字符,输入的个数可少于宽度指示。
例如:
int a,b,c;
scanf("%2d%2d%3d",&a,&b,&c);
程序执行时,若输入12345 67890,输出的a的值为12,b的值为34,c的值为5,因为5和6之间有一个空格,所以当读完5之后遇到空格,空格被认为数据输入结束。
格式字符串举例:
#include
main()
{
char c1
,c2
,c3
;
scanf("%3c%3c%3c",&c1
,&c2
,&c3
);
printf("c1=%c,c2=%c,c3=%c",c1
,c2
,c3
);
}
执行程序输入abcdefghijk123,对于类型c,只读入单个字符,加上宽度指示符后,第一个%3c读取三个字符abc,赋给字符变量c1,但char变量类型的c1中只能存放一个字符,所以c1中只能存放字符a,b和c省略。往后以此类推。
输出为:c1=a,c2=d,c3=g
赋值抑制字符*
表示本输入项对应的数据读入后,不赋值给相应的变量,该变量的数据将由下一个格式指示符指定的数据输入
例如:
int a,b,c;
scanf("%2d%*3d%2d%2d",&a,&b,&c);
printf("a=%d,b=%d,c=%d\n",a,b,c);
执行后若输入1234567890
a=12,b=67,b=89
当遇到*时被抑制,不进行赋值操作,舍去了345
(3)普通字符:scanf()函数中的普通字符必须原样输入,否则值会错误。知道就行,强烈不建议使用。
(4)scanf()函数的数据输入操作
要点一:当scanf()函数中的格式字符串中出现转义字符(如\n),系统并不把它当作转义字符来解释,从而产生一个控制操作,将其视为普通字符,所以也要原样输入。
要点二:输入数据时,遇到一下情况,系统认为该数据输入结束:
1.遇到空格,或者Enter键,或者按Tab键
2.遇到输入宽域结束,例如"%3d",只取3列
3.遇到非法输入。如在输入数值数据时,遇到字母等非数值符号,结束输入
4.使用格式说明符"%c"输入单个字符时,空格和转义字符均作为有效字符被输入。
25.2getchar()函数的格式
函数的原型:
int getchar (int ch);
函数功能:从标准输入设备(键盘)输入一个字符,并返回输入字符的ASCII值。
使用方法:ch=getchar(void);
如果只是想输入一个字符并输出,也可以在putchar()函数中嵌入getchar()函数,例如:putchar(getchar());
注意:
1.连续输入多个字符时,字符会被存入键盘缓冲区。
2.Enter键也是一个输入。
26.小数的输入和输出的注意事项
scanf()函数中float型(单精度浮点型)是%f,double型(双精度浮点型)是%lf或%le,字母l是英文单词long的首字母,其中%le是以指数的形式输入
printf()函数中float型和double型都是%f的形式,当以指数的形式输出时用%e
27.数据的存储
整型数据的存储
计算机处理的所有信息都以二进制形式表示,即数据的储存和计算都采用二进制。首先介绍整型数据的存储形式,不妨假设每个整数在内存中占用两个字节存储,最左边的一位(最高位)是符号位,0代表正数,1代表负数
数值可以采用原码、反码和补码等不同的表示方法。为了便于计算机内的运算,一般以补码表示数值。
正数的原码、反码和补码相同,即符号位是0,其余各位表示数值
例如:
1的补码是:(以15位为例)0000000000000001
127(2的7次方减一):(以15位为例)0000000001111111
两个字节的存储单元能表示的最大正数是2^15-1,即32767
32767的补码是:0111111111111111 (第一位0是符号位)
负数的原码、反码和补码不同:
(1)原码:符号位是1,其余各位表示数值的绝对值
(2)反码:符号位是1,其余各位对原码取反
(3)补码:反码加1
-1的原码是:1000000000000001
-1的反码是:1111111111111110
-1的补码是:1111111111111111
同理-32767的补码是:1000000000000001
-32767减一-32768
-32768的补码是:1000000000000000字符型数据的存储
字符型数据都是8位(8bit),即一个字节
每个字符在内存中占用一个字节,存储它对应ASCII数值。
例如字符'A'在ASCII码中的值为65,对应的二进制数为1000001
他在内存中对应的二进制码为01000001
28.while循环和do-while循环
循环有for循环,while循环,和do-while循环,其中for循环在前面已经说过了,这里只简单说一下while循环和do-while循环:
while循环:
while(表达式
)
{
...
};//最后的这个分号可要可不要
先判断表达式的值是否为真,判断的结果只有两个,要么为真,要么为假。真为1,假为0。如果为真,执行循环体中的语句,然后继续判断表达式的值是否为真,再次循环,以此往复,直到表达式的值为假时,不再进行循环。
do-while循环:
do
{
...
}while(表达式
);//最后的这个分号一定不能少
先进行循环体中的语句,然后计算表达式的值是否为真,如果为真继续执行循环体中的语句,再次进行判断,以此往复,直到表达式的值为假的时候不再进行循环。
无论是for循环、while循环还是do-while循环,只要在循环体中碰到了break;语句,立马退出循环。break;语句常与if判断语句结合使用,用if语句进行判断,达到某个条件的时候退出循环。当while语句后面括号中的判断语句为数字1时,即while(1),表示判断条件永远为真,永远进行循环,直到碰到break;语句时退出循环。
三:编程实战代码讲解(几个重要内容我直接放进代码中了)
1.重组一个三位数Recombine A Three Digit Number
先来看一个利用子函数和%求余数的举例
#include
int fun(int a
) //子函数写在主函数前面
{
int m
;
m
= a
% 10; //a除以10取余数,我们会得到它的个数位的值,并赋给m
return m
; //返回m值
}
main()
{
int a
, b
;
printf("please input a:\n"); //提示输入一个数
scanf_s("%d", &a
);//scanf_s只用在VS编译器中,其他编译器用scanf
b
= fun(a
); //子函数的调用,把返回的m值赋给b
printf("%d", b
); //输出b的值
}
这里的子函数直接写在主函数前面,所以不需要进行子函数声明
进入正题:
重组一个三位数,输入三个数,取a的个位数作为新数字的百位数,b的个位数作为新数字的十位数,c的个位数作为新数字的个位数,输出重新组成的三位数
//RecombineAThreeDigitNumber
#include
int fun(int a
, int b
, int c
) //C/C++语言标准库中没有fun函数,fun函数是自定义函数,是用来举例或作语法演示的,也可换成别的名称如abc等
{
int m
;
m
= a
% 10 * 100 + b
% 10 * 10 + c
% 10; //a除以10取余数乘以100+b除以10取余数乘以10+c除以10取余数
return m
;
}
main(void) //主函数完成数据输入以及结果输出部分,而fun函数实现对数据处理功能
{
int a
, b
, c
, d
;
printf("please input a & b & c:\n");
scanf_s("%d%d%d", &a
, &b
, &c
);//scanf_s只用在VS编译器中,其他编译器用scanf
d
= fun(a
, b
, c
);
printf("d=%d\n", d
);
}
输入样例:
34
56
233
输出样例:
463
2.常用的数学函数Common Mathematical Functions
计算个人所得税
#include
#include
int main()
{
int money
, year
;
double rate
, sum
;
printf("Enter money:");//输入金额
scanf_s("%d",&money
);//scanf_s只用在VS编译器中,其他编译器用scanf
printf("Enter year:");//输入年限
scanf_s("%d",&year
);//scanf_s只用在VS编译器中,其他编译器用scanf
printf("Enter rate:");//输入利率
scanf_s("%lf",&rate
);//scanf_s只用在VS编译器中,其他编译器用scanf
sum
= money
* pow(1 + rate
, year
);//用sum来保存计算金额
printf("sum=%.2f\n",sum
);//保留两位小数输出.2f意识是保留两位小数
return 0;
}
平方根函数sqrt(x) 计算根号下x sqrt(4.0)=2.0
绝对值函数fabs(x) 例如 fabs(-23)=23
幂函数pow(x,n) 例如 pow(2,10)=1024
指数函数exp(x) e的x次方
以e为底的对数函数log(x) 计算ln(x)
代码优化:
//CommonMathematicalFunctions
#include
#include //包含数学函数的头文件
int main()
{
int money
, year
;
double rate
, sum
;
printf("Enter the amount,year and exchange rate in turn:\n");
scanf_s("%d%d%lf", &money
, &year
, &rate
); //顺序必须对应
sum
= money
* pow(rate
+ 1, year
);
printf("sum=%.2f\n", sum
); //%.2f 意思是保留两位小数
return 0;
}
3.用if语句实现分段函数Calculating Piecewise Functions
//CalculatingPiecewiseFunctions
#include
int main()
{
double x
, y
;
printf("Enter x (x>=0):\n");
scanf_s("%lf",&x
); //scanf_s 里面的 %f 为float型, %lf 为double型
if (x
y
= 2.5 * x
- 10.5;
}
printf("y=f(%f)=%.2f\n",x
,y
); //%.2f保留两位小数
//printf里面的%f即为float型和double型
return 0;
}
//碰到if 为假,没有else 的情况时,直接跳过if语句执行后面语句
4.用科学计数法表示较大或较小的数
//用科学计数法表示较大或较小的数
#include
int main()
{
int a
;
double b
;
a
= 1.389e3;
b
= 2.70098E-2;
printf("%d%15.6f", a
, b
); //15为宽度,数据填不满宽度时用空格补,.6f保留6位小数
return 0;
}
5.输出华氏度转摄氏度转换表
//输出华氏度-摄氏度转换表
#include
int main(void)
{
int fahr
, lower
, upper
;
double celsius
;
printf("Enter lower:");//输入华氏度的下限
scanf_s("%d", &lower
);
printf("Enter upper:");//输入华氏度的上限
scanf_s("%d", &upper
);
if (lower
celsius
= (5.0 / 9.0) * (fahr
- 32);
printf("%4d %6.1f\n", fahr
, celsius
);
}
}
else
printf("Invalid Value!\n");//不可行时输出不合法数据
return 0;
}
6.输入一个数求阶乘(for循环来实现)
//输入一个数求阶乘
#include
int main()
{
int i
, n
, x
;
printf("Enter n:");
scanf_s("%d", &n
);
x
= 1;
for (i
= 1; i
int num
;
printf("Enter a number:\n");
scanf_s("%d",&num
);
if (num
%2==0)//该数除以2取余数是否为0
{
printf("The number is even.\n");//为0该数是偶数
}
else
{
printf("The number is odd.\n");//否则该数为奇数
}
return 0;
}
8.else-if进行四则运算
//四则运算
#include
int main()
{
double value1
, value2
;
char op
;//定义一个字符型变量
printf("Type in an expression:");
scanf_s("%lf", &value1
);
op
=getchar();//用getchar函数输入操作符
scanf_s("%lf", &value2
);
if (op
== '+')//判断操作符
printf("=%.2f", value1
+ value2
);
else if (op
== '-')//判断操作符
printf("=%.2f", value1
- value2
);
else if (op
== '*')//判断操作符
printf("=%.2f", value1
* value2
);
else if (op
== '/' && value2
!= 0)//判断操作符,操作符为除号,且除数不为零
printf("=%.2f", value1
/ value2
);
else
printf("操作错误!");
return 0;
}
9.任意给出三角形的三个边长,判断是否能够组成三角形
#include
main()
{
float a
, b
, c
;
printf("input the length of triangle:\n");
scanf_s("%f%f%f",&a
,&b
,&c
);
if (a
+ b
> c
&& a
+ c
> b
&& b
+ c
> a
)
printf("Can form a triangle!");
else
printf("Can not form a triangle!");
}
10.判断输入的是不是英文字母
//判断输入的字符是不是英文字母
#include
int main()
{
char ch
;
printf("Enter a character:");
ch
= getchar();
if ((ch
>= 'a' && ch
= 'A' && ch
if (ch
>= 'A' && ch
= 'a' && ch
if (ch
>= 'A' && ch
= 'a' && ch
double value1
, value2
;
char op
;
printf("Type in an expression:");
scanf("%lf%c%lf",&value1
,&op
,&value2
);
switch (op
)//switch括号里面的是我们要判断的对象
{
case '+': //如果op是加号,则执行该语句
printf("=%.2f\n", value1
+ value2
);
break;//执行完后用break来跳出switch语句
case '-': //如果op是减号,则执行该语句
printf("=%.2f\n", value1
- value2
);
break;
case '*': //如果op是乘号,则执行该语句
printf("=%.2f\n", value1
* value2
);
break;
case '/': //如果op是除号,则执行该语句
if (value2
!= 0)
printf("=%.2f\n", value1
/ value2
);
else
printf("ERROR\n");//如果除数为零,输出错误
break;
default: //如果op以上情况都不是
printf("Unknown operator!\n");//输出未知操作
break;
}
return 0;
}
14.判断成绩等级
用switch语句完成以下功能:输入一个百分制整数成绩,如果成绩为90-100,则等级为A;如果成绩为80-89,则等级为B;如果成绩70-79,则等级为C;如果成绩为60-69,则等级为D;如果成绩为0-59,则等级为E。
#include
int main()
{
int g
;
printf("请输入一个0到100到成绩:");
scanf("%d",&g
);
g
/=10; //对成绩进行除10运算,去掉个位数
switch (g
)
{
case 9:case 10:
printf("A");
break;
case 8:
printf("B");
break;
case 7:
printf("C");
break;
case 6:
printf("D");
break;
case 5:case 4:case 3:case 2:case 1:case 0:
printf("E");
break;
default:
printf("Input Error");
}
return 0;
}

15.goto语句与continue语句
#include
main()
{
int i
= 2, f
= 1, n
;
double s
= 1, t
;
printf("input n:\n");
scanf_s("%d",&n
);
a1
: //做一个记号
t
= 1.0 / (2 * i
- 1);//1.0C语言中带小数点的常量默认为double型小数
f
= -f
;
s
= s
+ f
* t
;
i
++;
if (i
item
= flag
* 1.0 / denominator
;
pi
= pi
+ item
;
flag
= -flag
;
denominator
= denominator
+ 2;
}
pi
= pi
* 4;
printf("%.4f",pi
);
return 0;
}
18.用嵌套循环打印一个高度为n的等腰三角型
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int n
, i
, j
;
printf("请输入等腰三角形的高度:");
scanf("%d",&n
);
for (i
= 1; i
int i
, j
, n
;
printf("请输入倒等腰三角形的高度:");
scanf("%d",&n
);
for (i
= 1; i
int count
, num
;
printf("Enter a number:\n");
scanf("%d",&num
);
//经常忘记循环前变量初始化
count
= 0;
while (num
!= 0)//代码很简单,自己理解一下
{
num
= num
/ 10;
count
++;
}
printf("%d",count
);
return 0;
}
21.猜数游戏
#include
#include //产生随机数需要的头文件
#include //产生随机数需要的头文件
int main()
{
int count
= 0, flag
, mynumber
, yournumber
;
srand(time(0));
mynumber
= rand() % 100 + 1;//产生的随机数很大,所以对100取余数,得到0到99之间的数,再加一得到1到100之间的数
flag
= 0;//循环变量初始化
while (count
printf("Lucky you!\n");
flag
= 1;
break;
}
else
if (yournumber
> mynumber
)
printf("Too big\n");
else
printf("Too small\n");
}
if (flag
== 0)
printf("Game Over!\n");
return 0;
}
22.从输入的一批以负数结束的成绩中选出最高分,用do-while语句实现
#include
int main()
{
int mark
, max
;
printf("Enter marks:");
scanf_s("%d", &mark
);
max
= mark
;
do
{
if (max
=
0);//while语句后面的分号可要可不要,但是do-while语句后的分号不能省去
printf("Max=%d\n", max
);
return 0;
}
23.使用for循环嵌套计算1!+2!+3!+4!+… …+100!
#include
int main()
{
int i
, j
;
double sum
, item
;
sum
= 0;
for (i
= 1; i
item
= item
* j
;
}
sum
= sum
+ item
;
}
printf("1!+2!+3!+4!+... ...+100!=%e",sum
);//%e以指数的形式输出最后的结果
return 0;
}
24.使用子函数求1!+2!+3!+4!+… …+100!
#include
double fact
(int n
);//声明一个子函数,结尾必须以分号结尾
//double为子函数的类型//fact为子函数名称
//括号里面的是参数,可以有一个或多个,也可以没有
//double为子函数返回值的类型,可以有返回值,也可以没有返回值
//没有返回值用void声明函数;如果什么都没有默认为整型
int main()
{
int i
;
double sum
;
sum
= 0;//不要忘记循环初始化
for (i
= 1; i
int i
;
double result
;
result
= 1;//不要忘记循环初始化
for (i
= 1; i
digit
= n
% 10;
n
/= 10;
printf("%d",digit
);
}
return 0;
}
26.使用嵌套循环输出100以内的全部素数
#include
#include
int main()
{
int i
, j
, n
, count
;
count
= 0;
for (i
= 2; i
printf("%6d",i
);
count
++;//对输出的个数进行计数
if (count
% 10 == 0)//每行输出的个数等于10个,则换行
printf("\n");
}
}
return 0;
}
27.穷举法的板砖解决方案问题,第一版
(DEV C++里面运行正常,VS里面会提示有病毒)
#include
int main()
{
int child
, men
, women
;
for (men
= 0; men
child
= 45 - women
- men
;
if (men
* 3 + women
* 2 + child
* 0.5 == 45)
printf("men=%d,women=%d,child=%d\n", men
, women
, child
);
}
return 0;
}
29.利用子函数求100以内的全部素数
#include
#include
int prime(int m
);
int main(void)
{
int count
, m
;
count
= 0;
for (m
= 2; m
printf("%6d", m
);
count
++;
if (count
% 10 == 0)
printf("\n");
}
}
return 0;
}
//注意for循环语句的执行顺序,先执行循环变量初始化,再执行进行循环的判断条件,符合条件,继续执行循环体语句,
//不符合条件,则不进行循环体语句。
int prime(int m
)
{
int i
;
for (i
= 2; i
double e
, pi
;
printf("Enter e:\n");//提示用户输入精度
scanf_s("%lf",&e
);
pi
= funpi(e
);
printf("pi=%f",pi
);
return 0;
}
double funpi(double e
)
{
int denominator
, flag
;
double item
, sum
;
denominator
= 1;
flag
= 1;
item
= 1;
sum
= 0;
while (fabs(item
) >= e
)
{
item
= flag
* 1.0 / denominator
;
sum
= sum
+ item
;
flag
= -flag
;
denominator
= denominator
+ 2;
}
return sum
* 4;
}
31.数字特征题

31.1代码一
#include
#include
int fun_1(int a
)
{
int c
;
c
= 0;
while (a
!= 0)
{
a
/= 10;
c
++;
}
return c
;
}
int fun_2(int a
, int b
)
{
int i
, digit
, er
;
er
= 0;
for (i
= 1; i
int num
, count
, i
, digit
;
count
= fun_1(a
);
num
= 0;
for (i
= 1; i
int n
, count
, two
, ten
;
scanf_s("%d", &n
);
if (n
>= 0 && n
int n
, x
, z
, w
= 0;
scanf_s("%d", &n
);
for (int i
= 1; n
>= 1; i
++)
{
x
= n
% 10;
n
/= 10;
if (x
% 2 == 0)
{
if (i
% 2 == 0)
z
= 1;
else
z
= 0;
}
else
{
if (i
% 2 == 1)
z
= 1;
else
z
= 0;
}
if (z
== 1)
w
+= pow(2, i
- 1);
}
printf("%d", w
);
return 0;
}
31.3代码三:
#include
#include
#include
int main()
{
char a
[10000];
int len
, i
;
int sum
= 0;
scanf_s("%s",&a
);
len
= strlen(a
);
for (i
=1;i
int num
, a
= 1, digit
= 0, count
= 1;
scanf_s("%d",&num
);
do
{
if ((num
+ count
) % 2 == 0)
{
digit
+= a
;
}
count
++;
num
/= 10;
a
*= 2;
} while (num
> 0);
printf("%d",digit
);
return 0;
}
31.5代码五
#include
#include
int main()
{
int n
,sum
=0;
scanf("%d",&n
);
while (n
>=0&&n
if(n
%10%2==i
%2)
sum
+=1*pow(2,i
-1);
n
/=10;
}
printf("%d",sum
);
break;
}
return 0;
}
31.6代码六
#include
int main()
{
int n
,er
=1,sum
=0,a
=1;
scanf("%d",&n
);
while(n
>0)
{
if(n
%10%2==a
%2)
sum
+=er
;
n
/=10;
er
*=2;
a
++;
}
printf("%d",sum
);
return 0;
}

还可以有很多种做法,只要能实现就可以。关键是取得代码的简洁易懂。
32.局部变量与全局变量
32.1局部变量
在程序中,使用的变量都定义在这个变量所在函数的内部,即花括号的内部(由一对花括号括起来的内容,复合语句,或称之为函数体),它们的有效使用范围被局限于所在的函数内部,即变量如果定义在一个复合语句的内部,那么该变量就是该复合语句的局部变量,其使用范围限制在该复合语句前后的花括号范围内所以主函数通过参数传递,把实参传递给其他子函数的形参,使用该形参来参与该子函数内部的运算;因此,子函数内部形参的改变,不会影响到主函数实参变量。变量的有效使用范围,保证了各函数的独立性,函数间的变量数据互不干扰。我们把定义在复合语句内部的变量,称之为局部变量(函数体也是一个大的复合语句),局部变量的有效作用范围限制在复合语句前后花括号内部。形参也是局部变量。复合语句就是由一对花括号括起来的语句,复合语句中还可以嵌套复合语句例如:

特别注意:在标准C语言中,变量必须定义在函数体的最顶部,但是在C++中可以把变量的定义放在函数的中间。现在大多数编译器都是同时支持C和C++的,所以可以把变量定义在函数体中间位置。如下代码for循环中的循环变量i就是定在for循环复合语句中的:
int main()
{//函数体开始
int n
;//n的使用范围限制在main函数体内部
n
= 10;
for(int i
; i
//复合语句开始
int a
=2; //复合语句内的局部变量
...
} //复合语句结束
}//函数体结束
32.2全局变量
定义在所有函数之外的变量就称之为全局变量。局部变量保证了各个函数之间数据的独立性,互不干扰,但是函数之间想要交流,就必须通过参数传递和函数调用,这样灵活性不强。所以就有了全局变量。全局变量的生命周期为:从它定义的地方开始,到整个程序的结束。定义全局变量保证了各个函数之间数据交流更加方便快捷。全局变量和局部变量可以重名。当局部变量和全局变量重名时,在该局部范围内局部变量有效
33.用函数实现财务现金记账。
#define _CRT_SECURE_NO_WARNINGS
#include
float cash
;//定义全局变量,用来保存金额值
void income(float number
), expend(float number
);//函数声明,一个函数类型名后面可以声明多个函数,每个函数中间用逗号隔开
int main()
{
int choice
;
float value
;
cash
= 0;
printf("Enter operate choice (0--end, 1--income, 2--expend):");
scanf_s("%d", &choice
);
while (choice
!= 0)
{
if (choice
== 1 || choice
== 2)//判断是否等于用==,不要用错成=,||是逻辑或,&&是逻辑与
{
printf("Enter cash value:");
scanf_s("%f", &value
);
if (choice
== 1)
income(value
);
else
expend(value
);
printf("current cash:%.2f\n",cash
);
}
printf("Enter operate choice (0--end, 1--income, 2--expend):");
scanf_s("%d",&choice
);
}
return 0;
}
void income(float number
)//无返回值函数,但可以用全局变量来保持子函数与主函数之间的联系
{
cash
= cash
+ number
;//改变全局变量
}
void expend(float number
)
{
cash
= cash
- number
;
}
34.变量生存周期和静态局部变量
34.1变量生存周期
变量是保存变化数据的单元,计算机用内存单元来对应实现。一旦在程序中定义变量,计算机在执行过程中就会根据变量类型分配相应的内存单元供变量保存数据。
主函数从一开始运行就给主函数中所有的局部变量分配了存储单元,到主函数运行结束,分配的存储单元被回收。而主函数中未被调用的子函数里面的变量(包括形参在内)未被分配存储单元,直到子函数被调用时,子函数里面被定义的变量(和形参)才被分配存储单元;一旦子函数调用结束,在子函数中定义的所有形参和局部变量将不复存在,相应的存储单元由系统收。根据这种特性,局部变量被称为自动变量。变量从定义开始分配存储单元,到运行结束存储单元被回收,整个过程称为变量生存周期。
34.2变量存储的内存分布
C语言把保存所有变量的数据区分成动态存储区和静态存储区。它们的管理方式完全不同,动态存储区是使用堆栈来管理的,适合函数动态分配与回收存储单元。而静态存储区相对固定,管理较简单,它用于存放全局变量和静态变量。
34.3静态变量
在静态存储区中,除了全局变量外,还有一种特殊的局部变量——静态局部变量。生存周期持续到程序结束。由于存储单元被保留,一旦含有静态局部变量的函数再次调用,则静态局部变量会被重新激活,上一次函数调用后的值仍然保存着,可供本次调用使用。
35.输出1!~n!(全局变量法)
#include
int f
= 1;//定义全局变量,并赋初始值为1
void fact_s(int n
);//定义无返回值函数,必须要写void,不写默认为整型
int main()
{
int i
, n
;
printf("Input n:");
scanf_s("%d",&n
);
for (i
= 1; i
f
= f
* n
;
}
36.while的妙用,统计输入的正整数中奇数和偶数的个数
#include
int main()
{
int x
, j
= 0, k
= 0;
printf("Enter x:");
while (scanf_s("%d", &x
))
{
if (x
float a
= 2.7;
int b
;
b
= (int)(a
+ 2.4) % 2;//把a+2.4的值强制转换成整型
printf("%i",b
);
return 0;
}
39.printf();函数的格式字符串的举例
#include
int main()
{
int x
= 12;
printf("%o\n",x
);//将十进制12转换为八进制数输出
printf("%#o\n",x
);//将十进制数12转换为八进制,然后以八进制的形式输出,八进制数开头第一个数为0,作为八进制的标志//0x为十六进制
return 0;
}
前面出现过这个代码,
40.求二元一次方程的解
40.1代码
#include
#include
int main()
{
double a
,b
,c
;
printf("请分别输入一个二元一次方程aX^2+bX+c=0的a、b、c的值:\n");
scanf("%lf%lf%lf",&a
,&b
,&c
);
(a
==1) ? printf("方程X^2%+gX%+g=0的解为:\n",b
,c
) : printf("方程% gX^2%+gX%+g=0的解为:\n",a
,b
,c
);
if (a
==0&&b
!=0) //a=0,b不等于0的情况
printf("X=%g",-c
/b
);
else if (b
==0&&a
==0) //a=b=0的情况
printf("X无解!");
else if (b
*b
-4*a
*c
>=0) //b的平方减4ac大于等于0有解的情况
(-b
+sqrt(b
*b
-4*a
*c
))==(-b
-sqrt(b
*b
-4*a
*c
)) //三目运算符,判断两个解是否相等
?
printf("X=%g",(-b
+sqrt(b
*b
-4*a
*c
))/(2*a
)) //两个解相等时,直接输出x的解
:
printf("X1=%g\nX2=%g",(-b
+sqrt(b
*b
-4*a
*c
))/(2*a
),(-b
-sqrt(b
*b
-4*a
*c
))/(2*a
)); //两个解不相等,分别输出x1和x2
else //以上情况都不是的情况,即b的平方减4ac小于0无解的情况
printf("X无解!");
return 0;
}
40.2调试

注意这里用到了%g,和%+g,其作用前面已经讲过了
41.爬楼梯问题,一次只能爬1阶或2阶,求爬到顶端共有多少种不同的方法,斐波那契数列
#include
int main()
{
int a
, b
, x
, n
, i
;
scanf_s("%d",&n
);
a
= b
= 1;
if (n
== 1)
printf("1");
if (n
>= 2)
{
for (i
= 1; i
int er
, ge
, i
, sum
;
i
= 0;
sum
= 0;
printf("请输入二进制数\n只能由1和0组成(输入的二进制数最大为1111111111):");
scanf_s("%d", &er
);//该段代码经过我精心调试过,输入的二进制数最大为十个1
while (er
!= 0)
{
ge
= er
% 10;
sum
= sum
+ ge
* pow(2, i
);
er
/= 10;
i
++;
}
printf("%d\n", sum
);
return 0;
}
该段代码经过我精心调试过,输入的二进制数最大为十个1超出范围的二进制数转换后并不正确。
43.十进制转二进制
#include
int main()
{
int n
,i
,j
;
printf("请输入一个十进制数,(该十进制数最大为2147483647):");
scanf_s("%d",&n
);
static int str
[31];
for (i
= 0; i
printf("%d",str
[j
]);
}
return 0;
}
44.二进制转换为十进制数值范围扩大
#include
#include //二进制转换为十进制需要数学函数
int main()
{
static int er
[31]; //定义一个静态的一维数组,系统会自动给每个数自动赋值0
int i
, j
, count
, sum
, k
, m
;
char digit
; //定义一个字符变量,我们要往里面输入数字
printf("请输入一个二进制数(该二进制数最大为1111111111111111111111111111111):\n");
count
= 0; //用count来统计二进制数的位数
for (i
= 0; i
er
[i
] = 1;
count
++; //统计一下位数
}
else if (digit
== '0') //如果输入的字符为‘0’,就给数组赋值为1
{
er
[i
] = 0;
count
++; //统计一下位数
}
else if (digit
== '\n') //如果输入了回车,则结束循环
break;
else //如果输入了0、1和回车以外的字符,则输出“输入错误!”
{
printf("输入错误!\n");
goto a
; //同时利用goto语句跳过下面的转换十进制的语句,提前结束主函数
}
}
sum
= m
= 0; //循环初始化
for (k
= count
- 1; k
>= 0; k
--) //之前统计的二进制位数会在这里用到
{
sum
= sum
+ er
[k
] * pow(2, m
); //转换公式
m
++;
}
printf("%d",sum
); //输出转换结果
a
: return 0;
}
int型变量sum能存储的最大十进制正数为2147483647,对应的二进制数为1111111111111111111111111111111,总共有31位数,所以不能用整型变量来存储这么大的数字,只能用一个长度为31的数组来存储,每个存储单元中只存储一个数字,分别对这些数字进行处理。静态的数组可以自动给每个数自动赋值为0。


45.一个重要的计算机计算误差案例

在上图中,我用scanf()函数输入了110和100分别给了speed和limit,然后我用printf()函数输出speed的值,因为double型显示到小数点后六位,所以输出的是110.000000,然后我再输出limit乘11(数据类型自动转换,11为整型,转换为limit的double型)再除以10(同样涉及到数据类型的自动转换),输出的结果也为110.000000。然后将limit乘11再除以10的值赋给x,比较x与speed之间的大小,如果speed小于x则输出1,否则不输出。运行结果也看到了,并且根据数学运算结果,肯定不小于,所以也没有输出1。这没毛病,但是我把代码改一下,问题就来了。

同样的代码,我只是改了1.1,可是运行的结果却不同。这个就涉及到浮点数精度的问题。输出的结果都相同,并且根据数学运算的结果也相同,但是在计算机中运算的结果却不相同。那么计算机中这个运算的误差为多少呢?


通过上面这两个案例,我们就可以看出运算结果的误差介于10的负13次方到10的负14次方之间。
下一篇文章
补充switch语句的内容和逗号运算符(C语言case后没有break的switch语句,会继续执行后面的语句再退出)C语言数组+内存编址+推箱子小游戏