C语言代码示范与讲解+C语言编程规范及基础语法+编程实战

上一篇文章:C语言程序设计概述+C语言简介+算法概述

C语言代码示范与讲解+C语言编程规范及基础语法+编程实战

一:代码示范集加讲解

1.C语言第一个代码:打印"This is the first C program!"

/*This is the first C program!*/
#include <stdio.h>	//编译预处理命令
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 <stdio.h>
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 <stdio.h>
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;定义一个整型数据,并给他赋初始值为3
  • printf("%d",n);引号里面的是要输出的内容,%d是要输出的整型数据,这个语句的意思是直接输出n的值。

2.2输出多个整数

#include <stdio.h>
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,1
  • int 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 <stdio.h>
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. 324000
  • float单精度浮点型数据,double双精度浮点型数据都是小数点后六位,double取值范围更大一些

2.4输入并输出多个整数和小数

#include <stdio.h>
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 <stdio.h>
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 <= a; i++)
	{
		fact = fact * i;	//花括号要上下对齐,格式美观,提高可读性,避免代码过多,可读性下降,也不利于后期维护
	}
	return (fact);
}

3.1思路描述

定义一个变量n,从键盘输入一个数赋给变量n,在printf();中调用子函数,将n的值传递给子函数的参数a,由a代替n在子函数中参与运算,运算结果存入变量fact,再将fact的值返回主函数调用该子函数的地方,然后printf();函数输出n的阶乘结果。

3.2详细讲解+for循环语句的执行顺序

  • 1.子函数
    当一个问题比较复杂的时候,我们会用到子函数。通常在编程的时候,我们面对一个大的问题,可以把这个大的问题拆解成几个小问题,大问题的框架用主函数来实现,小问题放在子函数来解决简单说用子函数来实现一个具体个功能,然后在主函数中来调用
  • 2.子函数的定义及调用
    • 定义函数类型 函数名 (参数表); 不写函数类型默认为int整型 定义无返回值的函数时,函数类型应为void例如只实现打印功能的子函数无返回值参数表中要写参数类型,且定义参数时只能一个一个定义不能同时定义多个。例如:int ZiHanShu(int a,int b,double e);int ZiHanShu(int a,b,double e);是不对的,因为a和b不能同时定义。子函数中的参数及变量与主函数中的变量互相独立,互不干扰子函数与主函数之间通过参数及返回值互相沟通联系。 子函数的返回值的类型子函数的类型保持一致
    • 调用:子函数调用时:子函数名称(想要传入的值);,例如factorial(n);,factorial是函数名称,n是我想要传入的值。注意:上面代码,子函数具体代码是在主函数下面写的,所以必须要在主函数前面声明,不声明无法正常使用。如果我将子函数具体代码写在主函数前面,则不需要提前声明。 就像这样:
#include <stdio.h>
int factorial(int a)
{
	int i, fact = 1;
	for (i = 1; i <= a; i++)
	{
		fact = fact * i;
	}
	return (fact);
}
int main(void)
{
	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 <stdio.h>	//编译预处理命令
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 <= n; i++)	//这里是一个for循环
	/*如果for循环后面只有一条语句,那么花括号可以省略*/
		fact = fact * i;	//for循环里面的一条语句
	return (fact);	//返回值可以加括号,也可以不加括号,通常情况下是不加的,了解一下就行了
}

二:C语言编程规范及基础语法

1.C语言编程规范

一个好的程序编写规范是编写高质量程序的保证清晰规范的源程序不仅仅方便阅读,更重要的是能够便于检查错误,提高调试效率,从而最终保证程序的质量可维护性。

  • 代码缩进统一为4个字符,不使用空格,要用Tab键制表位

2.常量、变量命名规范

#define CLASS 5	/*定义常量*/
int m_iClass;	/*定义整型成员变量*/
int iNumber;	/*定义普通整型变量*/
int * pClass;	/*定义指针变量*/

3.函数命名规范

函数命名可以采用“FunctionName”的形式。注意首字母要大写,其后的字母大小写混合。
#int AddTwoNum(int num1,int num2);

4.标识符

(1)标识符由字母、数字和下划线组成
第一个字符不能是数字只能是字母或下划线
区分大小写:大写字母与小写字母不同
C语言规定了一个标识符允许的字符个数,即标识符的前若干个字符有效,超过的字符将不被识别,定义标识符最大长度为8。
(2)C语言的标识符可分为关键字预定义标识符用户标识符三类
(3)预定义标识符
即预先定义并具有特定含义的标识符
(4)用户标识符:由用户根据需要定义的标识符称为用户标识符,用来给变量、函数、数组等命名

5.关键字

C语言预先规定了一批标识符,它们在程序中都代表着固定的含义,不能另作他用,这些字符称为关键字,例如:intdoubleifelsewhilefor

  • 关键字大全
    在这里插入图片描述
    在这里插入图片描述

6.C语言数据类型

在这里插入图片描述

7.常量定义格式

#define 标识符 常量数据
例如:
#define PI 3.14
定义了符号常量PI,在程序中所有需要用到3.14的地方,全部都可以写成PI
C语言中建议符号常量名使用大写,以区分于变量
符号常量一经定义,在程序中不得再次赋值
常量定义的举例:

//利用子函数求圆柱体的体积
#define _CRT_SECURE_NO_WARNINGS //宏定义
#include <stdio.h>
const double PI = 3.1415926;//用const定义常量,也可以#define PI 3.1415926
double cylinder(double r,double h);//r和h是形参
int main()
{
	double radius, height;

	printf("Enter radius and height:");
	scanf("%lf%lf",&radius,&height);
	printf("%.3f",cylinder(radius,height));//子函数调用的时候用实参
	return 0;
}
double cylinder(double r, double h)
{
	return PI * r * r * h;
}

解读:第一行宏定义,只在VS中使用,在其他编译器去掉第一行宏定义

8.计算机中的储存单位

最小的储存单位:bit,位
8bit=1byte(字节)
1024byte=1kb(千字节)
1024kb=1mb(兆字节)
1024mb=1gb(吉字节)
1024g=1tb(太字节)
往后还有很多更大的,这里不写了

9.整型数据

在C语言中整型常量可以以十进制、八进制、十六进制等形式出现
(1)十进制形式
(2)八进制形式:在数码前加数字0。例如:012034等,其中012=1乘8的1次幂+2乘8的0次幂=10(十进制)
(3)十六进制形式:在数码前加0x(数字0和字母X或x)。例如:0x120x3e0xff等,其中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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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<<b表示将a的二进制值左移b位。要求a和b都是整型,b只能为整数,且不能超过机器字所表示的二进制位数
      注意区别位逻辑运算和逻辑运算
      移位运算具体实现有三种方式:
      循环移位:移入的位等于移出的位
      逻辑移位:移出的位丢失,移入的位取零
      算术移位:在算术移位(带符号)中,移出的位丢失,左移入的位取0,右移入的位取符号位即最高位代表数据符号,保持不变。
      C语言中的移位运算方式与具体的C语言编译器有关,通常实现中,左移位运算后右端出现的空位补0,移至左端之外的位则舍弃;右移运算与操作数的数据类型是否带有符号有关,不带符号位的操作数右移位时,左端出现的空位补0,移至右端之外的位则舍弃,带符号位的操作数右移位时,左端出现的空位按符号位复制,其余的空位补0,移至右端之外的位则舍弃
      假设a=58=00111010,a<<2的值为:
      11101000=232=58*4
      左移一位相当于乘2,左移两位相当于乘4;右移同样的道理,只不过把乘改为了除
      注意移位运算不会改变原操作数的值,除非使用a<<=2;a=a<<2;
      (位逻辑运算有些晦涩难懂,这里简单了解一下,在后面的文章中,会做详细介绍)
  • 指针运算符
    *取内容符
    &取地址符

  • 其他运算符
    ()[]->.

  • 求字节长度运算符
    sizeof()

  • 强制类型转换符
    (类型符)

  • 赋值运算符以及复合赋值运算符
    =+=-=*=/=等等
    a+=b;相当于a=a+b;

  • 条件运算符
    表达式1 ? 表达式2 : 表达式3

  • 逗号运算符
    ,
    自左向右进行运算
    例如:printf("%d",(int a=1,b=2,c=3)); 最后的输出结果为3,逗号运算符最右边的数。逗号运算符在后面的博客中会补充。

15.自增自减的前置与后置

++i--i前置,先执行i=i+1(i=i-1),再把表达式的值参与其他运算
i++i--后置,先把表达式的值参与其他运算,再执行i=i+1(i=i-1)

  • 举个例子:
    int i=3,y;
    y=-i++;
    结果是y=-3,i=4
    这里i++看成一个整体,整体表达式的值为3,然后把-3赋给y,再执行i=i+1,最后i的值为4
  • 再举个例子:
#include <stdio.h>
main()
{
	int x=3,y,z;
	y=x++;
	z=++x;
	printf("x=%d,y=%d,z=%d",x,y,z);
}

结果是:x=5,y=3,z=5
同样的,x++看成一个整体,整体表达式的值为x的值,也就是3,将整体表达式的值赋给y,再执行x=x+1,x的值变为4。++x先执行x=x+1,x的值变为5,然后将5作为++x整体表达式的值赋给z。

16.关系运算符与关系表达式

关系运算符主要用于比较运算,比较后要么为真要么为假,如果为真结果为1,如果为假结果为0
<><=>=这四种关系运算符的优先级相同,并且这四种关系运算符的优先级高于==!===!=的优先级相同
不要把===混淆,==是判断两端的操作数是否相等,而=是将右侧操作数的值赋给左侧操作数。

18.逻辑运算符与逻辑表达式

逻辑表达式的值只能为真或者假,用0表示假,用1表示真。
! 逻辑非
&& 逻辑与
|| 逻辑或
举个例子:
int a=2,b=5;
!a对a取反,a的值为2,代表真,取反后结果为假,值为0
!(a+3>b)先算a+3>b,值为0,对零取反后值为1
!的优先级最高,其次是&&,最后是||

19.复合赋值运算符

C语言中复合赋值运算符有以下10个:
*=/=%=+=-=<<=>>=&=^=|=
举个例子:
x*=y相当于x=x*y
x*=z+y相当于x=x*(z+y)

20.运算符的优先级和结合性

按照优先级从高到低排序:

  • 括号优先级最高()
  • !
  • -+++--(类型名强制数据类型转换)sizeof()
  • */%
  • +-
  • <<=>>=
  • ==!=
  • &&
  • ||
  • 表达式1 ? 表达式2 : 表达式3(条件运算符)
  • =+=-=*=/=%=
  • , (运算符优先级最低的是逗号运算符)

21.其他运算符(条件运算符、求字节运算符)

  • 条件运算符
    条件运算符是三目运算符
    表达式1 ? 表达式2 : 表达式3;
    条件运算符的规则为:先计算表达式1的值,若它的值为真,则计算表达式2的值,并把它作为整个表达式的值;如果表达式1的值为假,则计算表达式3的值,并把它作为整个表达式的值。
    举个例子:
    max=x>y?x:y;
    先判断x>y是否成立,若成立,返回x的值,否则返回y的值
    C语言中条件运算符的优先级高于赋值运算符
    再举个例子:
    根据某员工的销售额计算销售提成,销售额小于等于1万,提成为5%,销售额大于1万小于等于2万,提成为8%,销售额大于2万,提成为10%。
#include <stdio.h>
main()
{
	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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
#include <math.h>

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 <stdio.h>
#include <math.h>	//包含数学函数的头文件

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 <stdio.h>

int main()
{
	double x, y;
	printf("Enter x (x>=0):\n");
	scanf_s("%lf",&x);				//scanf_s 里面的 %f 为float型, %lf 为double型
	if (x <= 15) {
		y = 4 * x / 3;
	}
	else {
		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 <stdio.h>
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 <stdio.h>
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 <= upper)//判断输入的数据是否可行
	{
		printf("fahr celsius\n");
		for (fahr = lower; fahr <= upper; fahr++)//用for循环实现转换表的打印输出
		{
			celsius = (5.0 / 9.0) * (fahr - 32);
			printf("%4d %6.1f\n", fahr, celsius);
		}
	}
	else
		printf("Invalid Value!\n");//不可行时输出不合法数据
	return 0;
}

6.输入一个数求阶乘(for循环来实现)

//输入一个数求阶乘
#include <stdio.h>
int main()
{
	int i, n, x;
	printf("Enter n:");
	scanf_s("%d", &n);
	x = 1;
	for (i = 1; i <= n; i++)
	{
		x = x * i;
	}
	printf("阶乘为%d", x);

	return 0;
}

7.输入一个数判断奇偶性

//Judging the parity of a number
#include <stdio.h>
int main()
{
	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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
int main()
{
	char ch;
	printf("Enter a character:");
	ch = getchar();
	if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
		printf("It is a letter.\n");
	else
		printf("It is not a character.\n");

	return 0;
}

11.英文大小写字母的转换

连续输入多个英文字母,以回车作为结尾,进行大小写字母互相转换。

#include <stdio.h>
int main(void)
{
	char ch;
	printf("input characters:");
	scanf("%c",&ch);
	while (ch != '\n')
	{
		if (ch >= 'A' && ch <= 'Z')
			ch = ch - 'A' + 'a';
		else if (ch >= 'a' && ch <= 'z')
			ch = ch - 'a' + 'A';
		putchar(ch);
		scanf("%c",&ch);
	}
	return 0;
}

第二种写法:

#include <stdio.h>
int main()
{
	char ch;
	printf("input characters:");
	while ((ch=getchar()!=\n)
	{
		if (ch >= 'A' && ch <= 'Z')
			ch = ch - 'A' + 'a';
		else if (ch >= 'a' && ch <= 'z')
			ch = ch - 'a' + 'A';
		putchar(ch);
	}
	return 0;
}

12.判断闰年

#include <stdio.h>
main()
{
	int year;
	printf("Please input year:\n");
	scanf_s("%d",&year);
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
		printf("%d is leap year!\n", year);
	else
		printf("%d is not leap year!\n",year);
}

13.switch语句的四则运算

#define _CRT_SECURE_NO_WARNINGS//宏定义,只在VS中使用,为了能够使用scanf函数,而不使用scanf_s
#include <stdio.h>
int main()
{
	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 <stdio.h>
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 <stdio.h>
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 <= n)
		goto a1;	//配合if语句实现循环,回到记号处再次执行
	printf("s=%7.5f\n",s);
}
/*
continue语句,在循环中如果碰到了continue语句,则跳过循环中continue以下的语句,进行下一次循环;如果碰到了break语句,则跳出循环。注意区分二者。
*/

16.使用格雷戈里公式求pi的近似值(while语句)

#include <stdio.h>
#include <math.h>
int main()
{
	int denominator, flag;
	double item, pi;

	//循环初始化
	flag = 1;
	denominator = 1;
	item = 1.0;
	pi = 1.0;

	while (fabs(item) >= 0.0001)//精确度为0.0001,当某项的值大于等于0.0001的时候执行while循环体语句,什么时候不大于等于了,什么时候结束循环
	{
		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 <stdio.h>
int main()
{
	int n, i, j;

	printf("请输入等腰三角形的高度:");
	scanf("%d",&n);

	for (i = 1; i <= n; i++)//外层循环控制三角形的层数
	{
		for (j = 1; j <= n - i; j++)//第一个循环打印该层的空格数,空格数与i值即层数有关
			printf(" ");
		for (j = 1; j <= i; j++)
			printf("c ");//打印c加一空格
		putchar('\n');//输出换行打印下一行
	}

	return 0;
}

19.用嵌套循环打印一个高度为n的倒三角

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int i, j, n;

	printf("请输入倒等腰三角形的高度:");
	scanf("%d",&n);

	for (i = 1; i <= n; i++)//与打印倒三角是同样的道理
	{
		for (j = n+1-i; j >= 1; j--)
			printf("c ");
		putchar('\n');
		for (j = 1; j <= i; j++)
			printf(" ");
	}

	return 0;
}

20.统计一个整数的位数

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	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 <stdio.h>
#include <stdlib.h>//产生随机数需要的头文件
#include <time.h>//产生随机数需要的头文件

int main()
{
	int count = 0, flag, mynumber, yournumber;
	srand(time(0));
	mynumber = rand() % 100 + 1;//产生的随机数很大,所以对100取余数,得到0到99之间的数,再加一得到1到100之间的数
	flag = 0;//循环变量初始化
	while (count < 7)//只能猜7次,7次猜不中就输了
	{
		printf("Enter your number:");
		scanf_s("%d",&yournumber);
		count++;//记下猜了多少次
		if (yournumber == mynumber)
		{
			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 <stdio.h>
int main()
{
	int mark, max;

	printf("Enter marks:");
	scanf_s("%d", &mark);
	max = mark;
	do
	{
		if (max < mark)
			max = mark;
		scanf_s("%d", &mark);
	}while (mark >= 0);//while语句后面的分号可要可不要,但是do-while语句后的分号不能省去
	printf("Max=%d\n", max);

	return 0;
}

23.使用for循环嵌套计算1!+2!+3!+4!+… …+100!

#include <stdio.h>
int main()
{
	int i, j;
	double sum, item;

	sum = 0;

	for (i = 1; i <= 100; i++)
	{
		item = 1;
		for (j = 1; j <= i; j++)
		{
			item = item * j;
		}
		sum = sum + item;
	}
	printf("1!+2!+3!+4!+... ...+100!=%e",sum);//%e以指数的形式输出最后的结果

	return 0;
}

24.使用子函数求1!+2!+3!+4!+… …+100!

#include <stdio.h>

double fact (int n);//声明一个子函数,结尾必须以分号结尾
//double为子函数的类型//fact为子函数名称
//括号里面的是参数,可以有一个或多个,也可以没有
//double为子函数返回值的类型,可以有返回值,也可以没有返回值
//没有返回值用void声明函数;如果什么都没有默认为整型
int main()
{
	int i;
	double sum;

	sum = 0;//不要忘记循环初始化

	for (i = 1; i <= 100; i++)
	{
		sum = sum + fact(i);//子函数的调用,函数名加(传入的参数i)
	}
	printf("1!+2!+3!+4!+... ...+100!=%e",sum);//%e是以科学计数法的形式输出,所以sum必须用双精度浮点型double来定义,否则结果会出错

	return 0;
}

double fact (int n)//传入的参数i的值给了n
{
	int i;
	double result;

	result = 1;//不要忘记循环初始化

	for (i = 1; i <= n; i++)
		result = result * i;

	return result;//函数返回值,值的类型与函数类型保持一致
}

25.逆序输出一个整数

#include <stdio.h>

int main()
{
	int n, digit;
	printf("Enter n:\n");
	scanf_s("%d",&n);

	while (n != 0)
	{
		digit = n % 10;
		n /= 10;
		printf("%d",digit);
	}

	return 0;
}

26.使用嵌套循环输出100以内的全部素数

#include <stdio.h>
#include <math.h>
int main()
{
	int i, j, n, count;

	count = 0;
	for (i = 2; i <= 100; i++)
	{
		n = sqrt(i);
		for (j = 2; j <= n; j++)
			if (i % j == 0)
				break;
		if (j > n)
		{
			printf("%6d",i);
			count++;//对输出的个数进行计数
			if (count % 10 == 0)//每行输出的个数等于10个,则换行
				printf("\n");
		}
	}

	return 0;
}

27.穷举法的板砖解决方案问题,第一版

(DEV C++里面运行正常,VS里面会提示有病毒)

#include <stdio.h>
int main()
{
	int child, men, women;

	for (men = 0; men <= 45; men++)
		for (women = 0; women <= 45; women++)
			for (child = 0; child <= 45; child++)
				if (men + women + child == 45 && men * 3 + women * 2 + child * 0.5 == 45)
					printf("men=%d,women=%d,child=%d\n", men, women, child);
/*使用三个for循环把所有可能的情况都循环一遍,把满足要求的数输出*/
	return 0;
}

28.穷举法搬砖问题第二版

(三个for循环的嵌套计算量太大,对于第一版的优化)

#include <stdio.h>
int main()
{
	int child, women, men;

	for (men = 0; men <= 15; men++)
		for (women = 0; women < 22; women++)//不要忘记后面的花括号,否则遍历循环之后,没有进行数据的输出,到最后程序运行的结果什么都没有
		{
			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 <stdio.h>
#include <math.h>
int prime(int m);
int main(void)
{
	int count, m;
	count = 0;
	for (m = 2; m <= 100; m++)
	{
		if (prime(m) != 0)
		{
			printf("%6d", m);
			count++;
			if (count % 10 == 0)
				printf("\n");
		}
	}
	return 0;
}

//注意for循环语句的执行顺序,先执行循环变量初始化,再执行进行循环的判断条件,符合条件,继续执行循环体语句,
//不符合条件,则不进行循环体语句。

int prime(int m)
{
	int i;
	for (i = 2; i <= sqrt(m); i++)
	{
		if (m % i == 0)
			return 0;
	}
	return 1;
}

30.利用子函数,利用格雷戈里公式求PI的近似值

#include <stdio.h>
#include <math.h>
double funpi(double e);
int main()
{
	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 <stdio.h>
#include <math.h>
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 <= b; i++)
	{
		digit = a % 10;
		a /= 10;
		if (digit % 2 == i % 2)
			er = er + 1 * pow(10, i - 1);
	}

	return er;
}
int fun_3(int a)
{
	int num, count, i, digit;
	count = fun_1(a);
	num = 0;
	for (i = 1; i <= count; i++)
	{
		digit = a % 10;
		a /= 10;
		num = num + digit * pow(2, i - 1);
	}
	return num;
}
int main()
{
	int n, count, two, ten;
	scanf_s("%d", &n);
	if (n >= 0 && n <= 1000000)
	{
		count = fun_1(n);
		two = fun_2(n, count);
		ten = fun_3(two);
		printf("%d", ten);
	}

	return 0;
}

31.2代码二:代码优化

#include <stdio.h>
#include <math.h>
int main()
{
	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 <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
	char a[10000];
	int len, i;
	int sum = 0;
	scanf_s("%s",&a);
	len = strlen(a);
	for (i=1;i<=len;i++)
	{
		int t;
		int x;
		t = a[len - i] - 48;
		if ((t + i) % 2 == 0)
			x = 1;
		else
			x = 0;
		sum = pow(2, i - 1) * x + sum;
	}
	printf("%d\n",sum);
	return 0;
}

31.4代码四

#include <stdio.h>
int main()
{
	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 <stdio.h>
#include <math.h>
int main()
{
	int n,sum=0;
	scanf("%d",&n);
	while (n>=0&&n<=1000000)
	{
		for(int i=1;i<8;i++)
		{
			if(n%10%2==i%2)
				sum+=1*pow(2,i-1);
			n/=10;
		}
		printf("%d",sum);
		break;
	}
	return 0;
}

31.6代码六

#include <stdio.h>
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 <= n; i++)//这里的循环变量i定义在for循环内部,所以其有效使用范围限制在该for循环中
	{
		...
	}
	//可以在复合语句内部直接嵌套复合语句
	{	//复合语句开始
		int a=2;	//复合语句内的局部变量
		...
	}	//复合语句结束
}//函数体结束

32.2全局变量

  • 定义在所有函数之外的变量就称之为全局变量。局部变量保证了各个函数之间数据的独立性,互不干扰,但是函数之间想要交流,就必须通过参数传递和函数调用,这样灵活性不强。所以就有了全局变量。全局变量的生命周期为:从它定义的地方开始,到整个程序的结束。定义全局变量保证了各个函数之间数据交流更加方便快捷
  • 全局变量和局部变量可以重名。当局部变量和全局变量重名时,在该局部范围内局部变量有效

33.用函数实现财务现金记账。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
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 <stdio.h>
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 <= n; i++)
	{
		fact_s(i);//无返回值函数的调用
		printf("%3d!=%d\n", i, f);
	}
	return 0;
}
void fact_s(int n)
{
	f = f * n;
}

36.while的妙用,统计输入的正整数中奇数和偶数的个数

#include <stdio.h>
int main()
{
	int x, j = 0, k = 0;
	printf("Enter x:");
	while (scanf_s("%d", &x))
	{
		if (x < 0)
			break;
		else if (x % 2 == 0)
			j++;
		else
			k++;
	}
	printf("偶数有%d个\n", j);
	printf("奇数有%d个", k);

	return 0;
}

注意,当输入了一串数字之后需要输入一个非数字的字符来结束这个while循环

37.条件运算符的应用(三目运算符)

#include <stdio.h>
int main()
{
	int sales;
	float tc;
	printf("please input sales:\n");
	scanf_s("%d", &sales);
	tc = sales > 20000 ? sales * 0.1 : (sales > 10000 ? sales * 0.08 : sales * 0.05);
	printf("%g", tc);//自动判断是%f还是%e,判断标准为占宽度最小的一种,且会省去小数点后无意义的0
	return 0;
}

三目运算符前面说过,这个代码也出现过,只是做了一个小小的修改

38.强制数据类型转换的举例

#include <stdio.h>
int main()
{
	float a = 2.7;
	int b;
	b = (int)(a + 2.4) % 2;//把a+2.4的值强制转换成整型
	printf("%i",b);
	return 0;
}

39.printf();函数的格式字符串的举例

#include <stdio.h>
int main()
{
	int x = 12;
	printf("%o\n",x);//将十进制12转换为八进制数输出
	printf("%#o\n",x);//将十进制数12转换为八进制,然后以八进制的形式输出,八进制数开头第一个数为0,作为八进制的标志//0x为十六进制
	return 0;
}

前面出现过这个代码,

40.求二元一次方程的解

40.1代码

#include <stdio.h>
#include <math.h>
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 <stdio.h>
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 < n; i++)
		{
			x = a + b;
			a = b;
			b = x;
		}
		printf("%d",x);
	}

	return 0;
}

42.二进制转十进制

#include <stdio.h>
#include <math.h>
int main()
{
	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 <stdio.h>
int main()
{
	int n,i,j;
	printf("请输入一个十进制数,(该十进制数最大为2147483647):");
	scanf_s("%d",&n);
	static int str[31];
	for (i = 0; i <= 30; i++)
	{
		str[i] = n % 2;
		n /= 2;
	}
	for (j = 30; j >= 0; j--)
	{
		printf("%d",str[j]);
	}
	return 0;
}

44.二进制转换为十进制数值范围扩大

#include <stdio.h>
#include <math.h>	//二进制转换为十进制需要数学函数
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 <= 30; i++)	//用for循环往数组里面输入数值,一次只输入一个一位数
	{
		digit = getchar();	//输入操作
		if (digit == '1')	//如果输入的字符为‘1’,就给数组赋值为1
		{
			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()函数输入了110100分别给了speedlimit,然后我用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次方之间。

下一篇文章

  • 40
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jackey_Song_Odd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值