BitpgC语言学习笔记


BitpgC语言学习笔记

01 初识C语言

1 什么是C语言

C是一门面向过程的计算机编程语言。
其编译器主要有GCC、Clang、MSVC等。

2 第一个C代码

国际惯例,打印Hello World!
#include <stdio.h>//头文件(某些库函数的调用,如printf)
int main()
{
	printf("Hello World!\n");
	return 0;
}
//解释:
//main()是主函数,为一个程序的入口
//一个工程中有且仅有一个main()

3 数据类型

种类:
1、char——字符型
2、int——整型
3、short——短整型
4、long——长整型
5、long long——更长的整型
6、float——(单精度)浮点型
7、double——双精度浮点型
*8、string——char型数组构造,C中无该数据类型

每种数据类型占用的内存大小:

#include <stdio.h>//头文件(某些库函数的调用,如printf)
int main()
{
	printf("%d\n",sizeof(char));
	printf("%d\n",sizeof(int));
	printf("%d\n",sizeof(short));
	printf("%d\n",sizeof(long));
	printf("%d\n",sizeof(long long));
	printf("%d\n",sizeof(float));
	printf("%d\n",sizeof(double));
	return 0;
}
//运行结果:1 4 2 4 8 4 8 

数据的多种类型目的为使描述实际问题时更加方便清晰。
如何使用数据类型:定义变量等。
在main函数中定义变量

#include <stdio.h>//头文件(某些库函数的调用,如printf)
int main()
{
	int a = 0;//整型
	char ch = 'b';//字符型
	float g = 200.0f;//单精度浮点型
	return 0;
}

4 变量、常量

生活中不变的值——常量(PI、性别、身份证号等)。
值可变的量——变量(身高、体重等)。

4.1 如何定义变量

语法:数据类型 变量名 = 初始值;

#include <stdio.h>
int main()
{
	int a = 0;//整型
	char ch = 'b';//字符型
	float g = 200.0f;//单精度浮点型
	return 0;
}

4.2 变量的分类

(1)局部变量
(2)全局变量

#include <stdio.h>
float global = 3.14159;//全局变量
int main()
{
	int local = 0;//局部变量
	float global = 2.62;//*当全局变量和局部变量名称一致时,局部变量优先
	printf("global = %d\n",global);
	return 0;
}
//打印结果global = 2.62

4.3 变量的使用

#define _CRT_SECURE_NO_WARNINGS 1  
#include <stdio.h>
float global = 3.14159;//全局变量
int main()
{
	double s = 0.0, r = 0.0;//s圆面积
	printf("请输入圆半径:\n");
	scanf("%lf", &r);//输入圆半径
	s = global * r * r;//圆面积的计算
	printf("s = %lf\n", s);
	return 0;
}
//scanf();输入
//printf();输出,数据类型对应:int——%d、float——%f、double——%lf、char——%c。

4.4 变量的作用域和生命周期

#define _CRT_SECURE_NO_WARNINGS 1  
#include <stdio.h>
float global = 3.14159;//全局变量
int main()
{
	double s = 0.0, r = 0.0;//s圆面积
	printf("请输入圆半径:\n");
	scanf("%lf", &r);//输入圆半径
	s = global * r * r;//圆面积的计算
	printf("s = %lf\n", s);
	return 0;
}
//global全局变量——作用域:整个工程中——生命周期:整个程序的生命周期,变量创建时开始至程序结束。
//s、r局部变量——作用域:main()的函数体{}中,该变量创建的局部范围——生命周期:变量从创建至销毁,进入作用域生命周期开始,出作用域生命周期结束。

4.5 常量

C中常量的分类:
1、字面常量
2、const修饰的变量——语法:const 变量名
3、枚举常量——语法:enum 枚举常量名{常量1,常量2,…};
4、#define 定义的标识符常量——语法:#define 常量标识符 常量值

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	//枚举常量
	enum sex
	{
		male,//0
		female,//1
		secret//2
	};//枚举常量的值从0开始,依次向下增1
	enum direction
	{
		east = 3,//3
		west,//4
		south,//5
		north//6
	};
	printf("male = %d\n",male);
	printf("female = %d\n", female);
	printf("secret = %d\n", secret);
	printf("east = %d\n", east);
	printf("west = %d\n", west);
	printf("south = %d\n", south);
	printf("nort = %d\n", north);

	3.14159;//字面常量
	2000;//字面常量

	const float pi = 3.14f;//const修饰的常变量,const 变量;指的是,此变量的值是只读的,不应该被改变。
	//pi = 2.63;此赋值语句会报错,提示pi不可修改
	printf("pi = %f\n",pi);

	#define max 10//#define修饰的标识符常量,表示max为一固定值
	int u = 0;
	u = max;
	printf("u = %d\n",u);//输出u = 10
	return 0;
}
//运行结果
//male = 0
//female = 1
//secret = 2
//east = 3
//west = 4
//south = 5
//nort = 6
//pi = 3.140000
//u = 10

//E:\Study Note\Program Study\C_code\Project3\Debug\Project3.exe (进程 2572)已退出,代码为 0。
//按任意键关闭此窗口. . .

注(常变量):
pi 被称为 const 修饰的常变量, 仅在语法层面限制了变量 pi 不能直接被改变,但是 pi 本质还是一个变量,所以叫常变量。

5 字符串|转义字符|注释

5.1 字符串

国际惯例中的”Hello World“,其双引号中的内容即为一串字符串。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()

{
	char arr[] = "Hello world";//末尾‘\0’结束字符串,但‘\0’被隐藏
	char arr1[] = { 'H','e','l','l','o',' ','w','o','r','l','d','\0' };
	char arr2[] = { 'H','e','l','l','o',' ','w','o','r','l','d' };
	printf("%s\n",arr);//Hello world,默认末尾\0结束字符串,但\0被隐藏
	printf("%s\n", arr1);//Hello world,手动加上\0.但\0不算做字符串的具体内容
	printf("%s\n", arr2);//Hello world烫烫烫烫蘃,该种表示,打印时会在内从中从‘H’开始按内存顺序逐一打印字符,直到在某一内存中找到‘\0’结束打印
	printf("%d\n", strlen(arr2));//strlen()求字符串长度,结果随机值,该种表示,从‘H’开始按内存顺序逐一计算,直到在某一内存中找到‘\0’输出计算结果
	printf("%d\n", sizeof(arr)/sizeof(char));//"Hello world"长度=12 含‘\0’
	printf("%d\n", sizeof(arr1) / sizeof(char));//长度=12
	printf("%d\n", sizeof(arr2) / sizeof(char));//长度=11
	return 0;
}

注:字符串的结束标志是一个 \0 的转义字符。sizeof是一个计算数据类型所占空间大小的单目运算符,在计算字符串的空间大小时,包含了结束符\0的位置;而strlen是计算字符串长度的函数,使用时需要引用头文件#include <string.h>,不包含\0,即计算\0之前的字符串长度。

5.2 转义字符

问题:如何打印文件存放的路径?( c:\code\test.c)

int main()
{
	printf("c:\code\test.c");
	//结果:c:code  est.c
	return 0;
}
//"\t"是一个转义字符——代表:水平制表符,而非字符"\t"

一些转义字符

转义字符意义ASCII值
\a响铃007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT) (跳到下一个TAB位置)009
\v垂直制表(VT)011
\’代表一个单引号039
\"代表一个双引号字符034
\\代表一个反斜线字符’‘’092
\?代表一个问号063
\0空字符(NUL)000
\ddd1到3位八进制数所代表的任意字符三位八进制
\xhh十六进制所代表的任意字符十六进制
int main()
{
	printf("c:\code\test.c\n");//c:code  est.c
	printf("c:\\code\\test.c\n");//完整打印路径c:\code\test.c
	printf("%c\n",'\'');//显示单引号,%c—单引号
	printf("%s\n","\"");//显示双引号,%s—双引号

	printf("%d\n",strlen("c:\code\test.c"));//12=10字符+2转义字符
	// C库函数strlen(str) 计算字符串str的长度,直到空结束字符,但不包括空结束字符。

	return 0;
}

5.3 注释

注释用来解释复杂代码或屏蔽不用的代码,语法://解释内容

6 选择语句

问题的选择:Yes——做事情A;No——做事情B;

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int input = 0;
	printf("你会好好学习C语言吗?键入“1 or 0”>:\n");
	scanf("%d",&input);
	if (input == 1)//选择
		printf("成长为C大佬\n");
	else
		printf("不好好学习回家卖红薯\n");
	return 0;
}

7 循环语句

某件重复事情的处理。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int line = 0;
	printf("加入比特开始写代码\n");
	while (line < 30000)
	{
		printf("努力努力继续敲代码,line = %d\n",line);
		line++;
	}
	if (line == 30000)
		printf("你会找到好工作\n");
	return 0;
}
//可以表示循环的方式:
/*  (1)while(结束条件)
	{
		循环体;
	}
	(2)for循环
	(3)do—while语句
*/

8 函数

函数是一个具体功能块,利用输入参数完成某项功能后返回给输出值。
f(x,y)=x+y——利用输入x、y,计算两数之和,返回给f(x,y)。f实现两数加法功能。
例:求两数和——用函数和不用函数的方式

int main()
{
	int x = 0, y = 0;
	scanf("%d%d", &x, &y);
	int sum = x + y;
	printf("sum = %d",sum);
	return 0;
}

将加法功能封装成Add(x,y)

int Add(int x, int y)
{
	int z = x + y;
	return z;
}
//Add函数实现加法功能
int main()
{
	int x = 0, y = 0;
	scanf("%d%d", &x, &y);
	int sum =Add(x,y);//需要计算两数之和时直接调用Add函数即可
	printf("sum = %d",sum);
	return 0;
}

9 数组

一组相同类型元素的集合——成为数组,种类:字符型数组、整型数组等;
数组的创建:
C99标准中:可定义变长数组,即arr[n]的定义方式正确,但该数组不能被初始化。
VS2019不支持C99标准。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	//数组的创建
	//10元素的整型数组,[]无指定数组大小时,由初始化确定大小,[]内为常量,不能给变量赋值再放入[]内部
	//元素初始化时位数不够,数组中自动填充"\0"补齐
	char arr[4][10] = { {'0','1','2','3'},{'a','b','c','d','e','f'},{ 'a','b','c','d','e','f' ,'\0','\0'},{ 'a','b','c','d','e','f' ,'0','0' } };
	return 0;
}

数组的访问:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	//数组的创建
	//10元素的整型数组,[]无指定数组大小时,由初始化确定大小
	//元素初始化时位数不够,数组中自动填充"\0"补齐
	char arr[4][10] = { {'0','1','2','3'},{'a','b','c','d','e','f'},{ 'a','b','c','d','e','f' ,'\0','\0'},{ 'a','b','c','d','e','f' ,'0','0' } };
	//数组的访问-通过下标进行,10元素一维数组,其下表0-9
	//arr[i],i=0—>9,即可访问arr中每一元素
	int i = 0, j = 0;
	for (i = 0; i < 4; i++)//行号循环
	{
		for (j = 0; j < 10; j++)//列号循环
		{
			printf("%c", arr[i][j]);
		}
		printf("\n");
	}

	return 0;
}

10 运算符

10.1 算术运算符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int result = 0;
	result = 5 + 6;//加
	printf("%d\n", result);
	result = 5 - 6;//减
	printf("%d\n", result);
	result = 5 * 6;//乘
	printf("%d\n", result);
	result = 5 / 6;//除—运算结果取商数,商0余5=0
	printf("%d\n",result);
	result = 5 % 6;//模—运算结果取余数,商0余5=5
	printf("%d\n", result);
	return 0;
}

10.2 移位运算符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 38;
	printf("%d\n", a);//将十进制数用二进制表示   0010 0110—>0*2^0+1*2^1+1*2^2+0*2^3+0*2^4+1*2^5
	int b = a << 1;//将a左移1位                 0010 0110
	printf("%d\n",b);//第一个0去掉,最后一位补0  0100 1100—>0*2^0+0*2^1+1*2^2+1*2^3+0*2^4+0*2^5+1*2^6
	int c = a >> 1;//将a右移1位                   0010 0110   
	printf("%d\n",c);//第一位补0,最后一位去掉   0001 0011
	return 0;
}

10.3 位操作符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	//位操作符
	int a = 1, b = 0, result = 0;
	result = a & b;//按位与
	printf("%d\n",result);
	result = a | b;//按位或
	printf("%d\n", result);
	result = a ^ b;//按位异或—按位将不一致的做或运算
	printf("%d\n", result);
}

10.4 单目操作符

操作数只有一个。

!          // 取反
-          // 负值
+          // 正值
&          // 取地址
sizeof     // 操作数的类型长度(以字节为单位)
~          // 对一个数的二进制按位取反(所有位:包含符号位)
--         // 前置、后置--,前置--:先减再用,后置--:先用再减
++         // 前置、后置++,前置++:先加再用,后置++:先用再加
*          // 间接访问操作符(解引用操作符) 
(类型)     // 强制类型转换

~运算时注意:
“机器数”的概念:一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,机器数的最高位存放符号,正数为0,负数为1。
“真值”:将带符号位的机器数对应的真正数值称为机器数的真值。
对于一个数,计算机要使用一定的编码方式进行存储,原码、反码、补码是机器存储一个具体数字的编码方式。
对于十进制数“+1”和“-1”有:
[+1] = [0000 0001]原= [0000 0001]反= [0000 0001]补
[-1] = [1000 0001]原= [1111 1110]反= [1111 1111]补

10.5 赋值操作符

= 		//a=x
+=		//a+=x—>a=a+x
-=		//a-=x—>a=a-x
*=		//a*=x—>a=a*x
/=		//a/=x—>a=a/x
&=		//a&=x—>a=a&x
^=		//a^=x—>a=a^x
|=		//a|=x—>a=a|x
>>=		//a>>=x—>a=a>>x
<<=		//a<<=x—>a=a<<x

10.5 关系操作符

==	<	>	<=	>=	!=(不等于)

10.6 逻辑操作符

&&	//逻辑与
||	//逻辑或

10.7 条件操作符(三目操作符)

语法:exp1 ? exp2:exp3;

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	//找最大值
	int a = 9, b = 5, max = 0, max1 = 0;
	if (a > b)
		max = a;
	else
		max = b;
	printf("%d\n",max);//if语句方式
	max1 = a > b ? a : b;
	printf("%d\n", max1);//利用条件操作符方式
}

10.8 逗号操作

语法:exp1, exp2, exp3, ……
其计算时从左至右依次计算,但结果为最后一个表达式的结果。

exp1 ? exp2 : exp3   //三目运算符 exp1成立,取exp2,否则取exp3

10.9 下标引用、函数调用和结构成员

[] () . ->  //->针对结构体指针

11 关键字

auto  break   case  char  const   continue  default  do   double else  enum   
extern float  for   goto  if   int   long  register    return   short  signed
sizeof   static struct  switch  typedef union  unsigned   void  volatile  while

11.1 typedef(类型重定义)

改变类型表示名称,例子中的unsigned int = u_int,简化表示。猫和咪的关系。

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

typedef unsigned int u_int;
//将unsigned int重新起名为u_int—类型重定义
int main()
{
	unsigned int a = 0;
	u_int a1 = 0;
	printf("a = %d;a1 = %d\n",a,a1);
	printf("%d %d\n",sizeof(a),sizeof(a1));
	//a=0;a1=0,a和a1数据类型长度都为4byte,32bit
	return 0;
}

11.2 static

static的作用:
(1)修饰局部变量:
下面两段代码中i的差异!

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

typedef unsigned int u_int; //将unsigned int重新起名为u_int—类型重定义

void test()
{
	int i = 0;
	i++;
	printf("%d\n",i);
}

int main()
{
	 u_int i = 0;
	for (i = 0; i < 10; i++)
	{
		test();//打印结果10个1
	}
	return 0;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

typedef unsigned int u_int;//将unsigned int重新起名为u_int—类型重定义

void test()
{
	static int i = 0;
	i++;
	printf("%d\n",i);
}

int main()
{
	 u_int i = 0;
	for (i = 0; i < 10; i++)
	{
		test();//打印结果1——10
	}
	return 0;
}

在这里插入图片描述
static修饰局部变量时改变了局部变量的生命周期,不再使得局部变量出范围被销毁。其实质是改变了局部变量的存储类型:将栈区的局部变量存储于静态区。
注:存储类型:

(2)修饰全局变量:

//代码1
//add.c
#define _CRT_SECURE_NO_WARNINGS 1

int g_val = 2024;
int add(int x,int y)
{
	return x+y;
}

//c_20240328.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

extern int g_val;
int main()
{
	printf("%d\n", g_val);//add.c中定义全局变量在c_20240328.c中使用
	return 0;
}
//代码2
//add.c
#define _CRT_SECURE_NO_WARNINGS 1

static int g_val = 2024;
int add(int x,int y)
{
	return x+y;
}

//c_20240328.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

extern int g_val;//声明全局变量
int main()
{
	printf("%d\n", g_val);//add.c中static修饰的全局变量在c_20240328.c中使用
	return 0;
}

代码1运行结果:2024
代码2运行结果:
1>c_20240328.obj : error LNK2001: 无法解析的外部符号 _g_val
1>E:\Study Note\Program Study\C_code\Project6\Debug\Project6.exe : fatal error LNK1120: 1 个无法解析的外部命令。报链接型错误!
当static修饰全局变量时,该全局变量只能在源文件中使用,不能在其他.c文件中使用。将全局变量的外部链接属性改为内部链接!
(3)修饰函数:

//代码1
//add.c
#define _CRT_SECURE_NO_WARNINGS 1

int add(int x,int y)
{
	return x+y;
}

//c_20240328.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

extern int add(int,int)//函数声明
int main()
{
	add(3,4);
	printf("%d\n",add(3,4));
	return 0;
}
//代码2
//add.c
#define _CRT_SECURE_NO_WARNINGS 1

static int add(int x,int y)//static修饰函数
{
	return x+y;
}

//c_20240328.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

extern int add(int,int)//函数声明
int main()
{
	add(3,4);
	printf("%d\n",add(3,4));
	return 0;
}

代码1运行结果:7
代码2运行结果:
1>c_20240328.obj : error LNK2019: 无法解析的外部符号 _add,函数 _main 中引用了该符号
1>E:\Study Note\Program Study\C_code\Project6\Debug\Project6.exe : fatal error LNK1120: 1 个无法解析的外部命令。报错!
当static修饰函数时,其作用与修饰全局变量类似。被修饰函数仅在自己所在源文件内使用,其他.c文件不能使用。

12 #define(预处理指令)

define修饰的常量和宏。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//#define定义常量
#define max 10//之后用到max的地方均用10计算。
int main()
{
	printf("%d\n",max);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//#define定义宏
#define add(u,v) u+v//通常为避免bug,将u+v写成((u)+(v))
#define add1(x,y) ((x)+(y))
int main()
{
	int sum = 0;
	sum = add(3, 4);
	printf("%d\n", max);
	printf("%d\n", 4 * add(3, 4));//打印结果:16—>运算时4*3+4
	printf("%d\n", 4 * add1(3, 4));//打印结果:28—>运算时4*(3+4)
	return 0;
}

13 指针

13.1 内存

(1)内存:计算机硬件之一,用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。内存是与CPU沟通的桥梁,计算机中所有程序的运行都要依靠内存。
(2)内存的IC元件包含:地址信号、数据信号、电源信号以及控制信号。地址信号的引脚数量决定了内存可以存放的数据。例:有10个地址线,即可以指定2^10个地址。数据信号的引脚数量决定每次可以输入输出的数据的多少。例:有8个数据线,即每次可以输入输出8bit数据。控制信号主要有写信号WR和读信号RD。当WR为1时表示写;当RD为1时表示读。
(3)内存的使用:
场景:n栋宿舍楼中的具体一栋(第8栋),共计n(n=256)间房子,门牌号记为:(8-1)~(8-256)。
32位机器:有32根物理地址线,地址线通电产生电信号(高电平或低电平),高低电平转化为数字信号(0或1)因此:[一根地址线] 产生 [一个电流信号(高/低电平)] 转化 [一个数字信号(0/1)]。
32根地址线合在一起就会有32bit的二进制序列,电信号转化为数字信号有2^32种二进制序列。
定义一个二进制序列为一个内存单元的编号/内存单元的地址/指针,即有2^32个字节(4GB)的内存空间。

指针变量的定义:

int main()
{
	//不同类型指针变量的定义和初始化
	int a = 20;
	int* p = &a;//定义指针类型变量p,并用变量a的地址来对指针变量p进行初始化
	*p = 10;//通过地址间接修改变量a的值
	printf("%d\n", a);
	char w = 'b';
	printf("%c\n", w);
	char* p_ch = &w;
	*p_ch = 'B';
	printf("%c\n", w);

	//指针变量的大小
	printf("%d byte\n", sizeof(int*));//运行结果:4 byte
	printf("%d byte\n", sizeof(short*));//运行结果:4 byte
	printf("%d byte\n", sizeof(double*));//运行结果:4 byte
	printf("%d byte\n", sizeof(long*));//运行结果:4 byte
	printf("%d byte\n", sizeof(long long*));//运行结果:4 byte
	printf("%d byte\n", sizeof(float*));//运行结果:4 byte

	return 0;
}

结果一致表明存放变量地址的空间都是一样的,原因:
机器类型32bit,对应的地址数量有2^32种,每个地址的二进制序列为32bit=4byte,故32位机器下所有指针变量的大小均为4byte。
机器类型64bit,对应的地址数量有2^64种,每个地址的二进制序列为64bit=8byte,故32位机器下所有指针变量的大小均为8byte。

13.2 指针的使用

&、*操作符的使用。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a;//申请内存空间,int——4byte
	a = 10;//初始化
	printf("%p\n",&a);//打印a的地址,&取地址符
	return 0;
}

运行结果:
0x00effb2c(运行结果不唯一)。
0x00EFFB2C 10 0 0 0
0x00EFFB30 204 204 204 204
0x00EFFB34 170 204 213 63

内存地址1byte(0x00EFFB2C)2byte(0x00EFFB2D)3byte(0x00EFFB2E)4byte(0x00EFFB2F)-
0x00EFFB2C10000十进制
0x00EFFB2C0a000000十六进制
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{

	int a = 10;
	int* p = &a;//定义指针变量p(指针=地址),*表示p为指针变量,int表明p执行的对象是int类型的
	//*p = 20;//通过地址间接修改内存中的值
	printf("%p\n",&a);//打印a的地址
	printf("%p\n",p);//打印a的地址
	printf("%d\n",*p);//打印地址p中存放的值(*:解引用—相当于从盒子中拿东西)
	//指针p的值和变量a的地址值相等,指针p保存了变量a的地址,*p内存间接寻址,可找内存对应地址存放的整数10
	return 0;
}

14 结构体

用来描述复杂对象,可以自行创建复杂对象类型。
语法:struct 对象名={变量1类型 变量1;变量2类型 变量2;……};

//操作符 . ->的使用
//.为结构成员访问操作符  用于结构体变量访问成员
//->操作符  用于结构体指针变量访问成员变量
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//结构体的定义
struct stu
{
	char name[20];
	double score;
	int age;
};
int main()
{
	//结构体的创建和初始化
	struct stu s = { "张三", 90.5,23 };
	printf("1:%s %lf %d\n", s.name, s.score, s.age);
	struct stu* p = &s;
	printf("2:%s %lf %d\n", p->name, p->score, p->age);
	printf("3:%s %lf %d\n",(*p).name, (*p).score,(*p).age);
	return 0;
}

输出结果:
1:张三 90.500000 23
2:张三 90.500000 23
3:张三 90.500000 23

15 分支语句if和switch

15.1 if语句

语法结构:

	if (表达式) //条件表达式
		语句1; //当条件表达式为真:执行语句1
	else
		语句2; //当条件表达式为真:执行语句2

C语言中关于“真\假”定义:非0即真,否则为假
语句的定义:;隔开的即为语句,单独;为空语句
if语句的三种结构:

	if (表达式) //条件表达式
		语句1; //当条件表达式为真:执行语句1
	if (表达式) //条件表达式
		语句1; //当条件表达式为真:执行语句1
	else
		语句2; //当条件表达式为假:执行语句2
	if (表达式1) //条件表达式
		语句1; //执行语句1
	else if (表达式2) 
		语句2; //执行语句2
	else
		语句3; //执行语句3

例:根据输入年龄输出其所在年龄段称呼

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int age = 0;
	printf("请输入年龄:");
	scanf("%d", &age);
	if (age <= 18)
	{
		printf("未成年\n");
	}
	else if (age > 18 && age <= 26)//(18 < age <=26)为错误写法,若age=20,则18<20为真=1,再执行1<=26仍为1
	{
		printf("青年\n");
	}
	else if (age > 26 && age <= 40)
	{
		printf("中年\n");
	}
	else if (age > 40 && age <= 60)
	{
		printf("壮年\n");
	}
	else if (age > 60 && age <= 100)
	{
		printf("老年\n");
	}
	else
	{
		printf("老神仙\n");//{}括起来的多条语句称代码块,若无{},则else下执行完选择语句后紧接着直接执行后续语句
	}
	return 0;
}

if-else语句嵌套使用时需要注意代码书写规范,否则易写BUG,使代码难以理解或理解出错。
if和else的匹配——>else和临近的if相匹配
代码风格的养成,学习借鉴高质量代码,理解别人的书写风格,常敲代码形成自己的风格
《高质量C/C++编程》的学习,学习代码书写规范。
if选择语句的练习:

  1. 任意输入一个数,判断其是否是奇数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 0;
	printf("请键入数据:");
	scanf("%d", &a);
	if (a % 2)//表达式(a % 2)用来判断a是否能被2整除,%运算:取余
	{
		printf("%d是奇数", a);
	}
	else
	{
		printf("%d不是奇数", a);
	}
	return 0;
}
  1. 输出1-100之间的所有奇数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 1;
	printf("方法1:\n");
	for (a = 1; a <= 100; a++)
	{
		//方法1
		if (a % 2)
		{
			printf("%d ", a);
			if (a == 99)
			{
				printf("\n");
			}

		}
	}
	//方法2
	printf("方法2:\n");
	for (a = 1; a <= 100; a += 2)
	{
		printf("%d ", a);
	}
	return 0;
}

15.2 switch语句

语法:

	switch (整型表达式)
	{
		case (整数或整型表达式) : 语句1;//case进入,break出
			break;//若没有break,执行完case后会接着执行下一个case
		case 2: 语句2;
			break;
		default:语句3; 默认
	}

例:键入数字,输出星期几

//代码1
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 0;
	printf("请键入数字:\n");
	scanf("%d", &a);
	switch (a)
	{
	case 1:
		printf("星期1\n");
	case 2:
		printf("星期2\n");
	case 3:
		printf("星期3\n");
	case 4:
		printf("星期4\n");
	case 5:
		printf("星期5\n");
	case 6:
		printf("星期6\n");
	case 7:
		printf("星期7\n");//每个case后不加break
	}
	return 0;
}

输出结果如下图:

键入1后执行完case1紧接着按顺序执行case2—case7,故输出结果非预期。

//代码2
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 0;
	printf("请键入数字:\n");
	scanf("%d", &a);
	switch (a)
	{
	case 1:
		printf("星期1\n");
		break;
	case 2:
		printf("星期2\n");
		break;
	case 3:
		printf("星期3\n");
		break;
	case 4:
		printf("星期4\n");
		break;
	case 5:
		printf("星期5\n");
		break;
	case 6:
		printf("星期6\n");
		break;
	case 7:
		printf("星期7\n");
		break;
	}
	return 0;
}


键入2后程序从case2进入,执行完打印功能后从break跳出。
键入1—之外的其他数:

键入9,程序无任何响应。此时可利用default来响应非1—7的任意数,例如打印输入错误。

//代码3
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 0;
	printf("请键入数字:\n");
	scanf("%d", &a);
	switch (a)
	{
	case 1:
		printf("星期1\n");
		break;
	case 2:
		printf("星期2\n");
		break;
	case 3:
		printf("星期3\n");
		break;
	case 4:
		printf("星期4\n");
		break;
	case 5:
		printf("星期5\n");
		break;
	case 6:
		printf("星期6\n");
		break;
	case 7:
		printf("星期7\n");
		break;
	default:
		printf("输入数据错误\n");
	}
	return 0;
}

default位置任意,不影响其作用。

switch语句练习题:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int n = 1, m = 2;
	switch (n)//n=1,进入该选择语句
	{
	case 1: m++;//执行m++,m=3
	case 2: n++;//无break,执行n++,n=2
	case 3://无break,执行case3,进入嵌套switch语句中
		switch (n)//此时n=2
		{
		case 1: n++;//略过,n=2
		case 2: n++; m++;//n=2,执行n++,m++,n=3,m=4
			break;//break跳出至上一层switch语句中
		}//跳出后外层switch的case3后无break
	case 4: m++;//执行m++,m=5
		break;//跳出外层switch语句
	default :
		break;
	}
	printf("m = %d,n = %d", m, n);//打印结果

	return 0;
}

结果:

16 循环语句while、for、do-while

16.1 while循环

//语法:
while(表达式)
	{
		循环语句;
	}
//break在while中的用法
while(表达式)
	{
		语句1break;//直接跳出循环,用于永久终结循环(语句2不执行直接跳出循环体)
		语句2;
	}
//continue在while中的用法
while(表达式)
	{
		语句1continue;//跳过本次循环直接进入表达式判断是否进行下一次循环(语句2不执行)
		语句2;
	}

例:
(1)用while循环打印1-20

//(1)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 20) 
	{
		printf("%d ", i);
		i++;
	}
	return 0;
}


(2)用while循环打印1-20,打印到10后显示程序终止(break)

在这里插入图片描述

//(2)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 20) 
	{
		printf("%d ", i);
		if (i == 10)
		{
			printf("程序终止\n"); 
			break;
		}
		i++;
	}
	return 0;
}


(3)用while循环打印1-20,在10和11中间加入C_code的打印结果(continue)
在这里插入图片描述
若不在continue前加i++语句,程序代码会在i=10处陷入死循环。

//(3)的错误示范
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 20) 
	{
		printf("%d ", i);
		if (i == 10)
		{
			printf("C_code\n"); 
			continue;
		}
		i++;
	}
	return 0;
}


此结果表明:光标闪烁表明程序仍在执行中,i++前continue会使while循环陷入死循环。具体分析,i=1、2、3、4、5、3、6、7、8、9时循环体打印i,打印完9后执行i++——>i=10,循环进入判断时10<20程序执行打印10,下一步i=10进入if中打印C_code,再执行continue时仍然是i=10,故程序会陷入i=10时的死循环中一直执行。

//(3)正确表示
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 1;
	while (i <= 20) 
	{
		printf("%d ", i);
		if (i == 10)
		{
			printf("C_code\n"); 
			i++;//在continue前进行循环变量自增,保证再次进入判断时循环变量不在保持为if条件中值
			continue;
		}
		i++;
	}
	return 0;
}

在这里插入图片描述
案例分析:
场景1:
从键盘输入密码,密码确认无误输入Y并打印确认成功;密码有误输入N并打印确认失败

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//123456
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}

	return 0;
}

运行结果:
在这里插入图片描述
输入123456后,程序跳过Y/N的输入确认步骤直接提示确认失败。
代码未按照逻辑运行原因分析:
在这里插入图片描述
程序运行逻辑
S1:提示输入密码;
S2:键盘输入123456暂存至缓存区,注键盘录入时回车结束,故缓存实际录入为:123456\n,scanf拿走123456存在password中,缓存区剩下\n;
S3:提示输出确认信息(Y/N);
S4:printf(“请确认密码(Y/N):>”);语句执行完成后不等键入字符,getchar()读取缓存区剩下的\n;
S5:if判断ch=‘\n’不等于’Y’,直接输出确认失败,程序结束。
问题解决:

int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//密码:123456;键入后缓存取实际字符串为:123456\n
	printf("请确认密码(Y/N):>");
	getchar();//清缓存
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

清除缓存区内容后运行逻辑正确。但存在一个新问题,getchar每次只拿走一个字符,若输入密码为:1234 56其结果仍不对。
在这里插入图片描述
再次修改程序如下:

int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);//密码:123456;键入后缓存取实际字符串为:123456\n
	printf("请确认密码(Y/N):>");
	//清缓存方式1:该场景中字符串不能存在空格,如:1234 56
	//getchar();
	//清缓存方式2
	int temp = 0;
	while (temp = getchar() != '\n')
	{
		;
	}//从缓存区循环拿走字符,直到拿走的字符为'\n'时跳出循环
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}

	return 0;
}


在这里插入图片描述
疑问:scanf和getchar从键盘键入数据暂存在同一个缓存区?

场景2:
在这里插入图片描述

int main()

{
	int ch = 0;
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch > '9')
			continue;
			putchar(ch);
	}
	return 0;
}

按照ASCII码表,当键入字符’0’——‘9’时跟随输出’0’——‘9’,键入其余字符不做反应。

16.2 for循环

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 1;//循环变量初始化——1
	while (i <= 20) //循环条件判断——2
	{
		printf("%d ", i);
		i++;//循环变量自操作——3
	}
	return 0;
}

用while循环时,当程序复杂化时1、2、3位置分散,修改循环时任意一个不满足while循环出现BUG。for循环即可方便管理1、2、3循环要素。for循环语法:

for (exp1;exp2;exp3)//exp1:循环变量初始化,exp2:循环条件判断,exp3:循环变量自操作
{
	循环体:
]

例:利用for循环打印0—9;

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	
	int i = 0;
	for (i = 0; i < 10; i++)//i=0:循环变量赋值;i<10:循环条件判断;i++:循环变量自操作
	{
		printf("%d ", i);
	}
	return 0;
}

for循环流程图解:
在这里插入图片描述

注:关于for循环使用的2个建议:1、不在循环体内进行循环变量的修改,防止循环失控。2、for循环变量的取值遵循“前闭后开”原则。

//1:循环体内修改循环变量
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", i);
		i++;//循环体内修改循环变量
	}
	return 0;
}

在这里插入图片描述
代码运行结果非预期。

//2:循环变量取值“前闭后开”
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)//“前闭后开”:赋初值为前,限范围为后
	//for (i = 0; i <= 10; i++)//“前闭后闭”
	{
		printf("%d ", i);
	}
	return 0;
}

for循环的变形:(语法形式)

//变形1:
for (;;)//全部省略写法。当循环条件省略时,默认循环判断值为恒“1”,故程序会陷入死循环
{
	循环体:
]
//变形2:
for (exp1,exp2;exp3 && exp4;exp5,exp6)
{
	循环体:
]
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0, j = 0;
	for (i = 0, j = 0; i < 2 && j < 5; i++, j++)
	{
		printf("BIT ");//结果打印两次BIT 
	}
	return 0;
}

for循环的嵌套:
//打印100次BIT

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0, j = 0;
	for (i = 0; i < 10; i++)
	{
		for (j = 0; j < 10; j++)
		{
			printf("BIT ");
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述
思考:下面代码的循环次数时多少?
答案:循环次数为0;循环条件判断语句为一赋值语句,将0赋给k,则判断恒为假,不执行循环体内容。

//请问循环要循环多少次? 
#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0;
}

16.3 do-while循环

//语法:
do
 循环语句;//循环语句可能非一句,{}括起来的代码块也可
while(表达式);

,场景有限,一般不使用。
循环流程:
在这里插入图片描述
先执行循环体,再进行条件判断,循环体至少执行一次。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0;
	do
	{
		printf("%d ", i);
		i++;
	} while (i < 10);
	return 0;
}

do-while中的break和continue

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0;
	do
	{
		printf("%d ", i);
		if (5 == i)
		break;
		i++;
	} while (i < 10);
	return 0;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0;
	do
	{
		printf("%d ", i);
		if (i == 5)
		continue;
		i++;
	} while (i < 10);
	return 0;
}
//类似while循环,程序陷入死循环,一致输出5

16.4 练习

1、计算10!
2、计算1!+2!+3!+······+10!
3、在一个有序数组中查找具体的每个数字n。编写int binsearch(int x,int v[],int n);功能:在v[0]<=v[1]<=v[2]<=······<=v[n-1]的数组中查找x
4、编写代码,演示多个字符从两端移动,向中间汇聚
5、编写代码实现,模拟用户登陆场景,并且只能登陆三次。(只允许输入三次密码,若密码正确提示登录成功,若三次均输入错误,退出程序)

//计算10!
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i1 = 0,j1 = 1;

	do
	{
		j1 = j1 * (i1 + 1);
		i1++;
	} while (i1 < 10);
	printf("1:10! = %d\n", j1);

	int i2 = 0, j2 = 1;

	for (i2 = 0; i2 < 10; i2++)
	{
		j2 = j2 * (i2 + 1);
	}
	printf("2:10! = %d\n", j2);

	int i3 = 0, j3 = 1;

	while (i3 < 10)
	{
		j3 = j3 * (i3 + 1);
		i3++;
	}
	printf("3:10! = %d\n", j3);




	return 0;
}

在这里插入图片描述

//2、计算1!+2!+3!+······+10!
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int i = 0, m = 1, n = 0;
	for (i = 0; i < 10; i++)
	{
		m = m * (i + 1);
		n += m;
	}
	printf("result = %d\n", n);

	return 0;
}

在这里插入图片描述

//3、在一个有序数组中查找具体的某个数字n。编写int binsearch(int x,int v[],int n);功能:在v[0]<=v[1]<=v[2]<=······<=v[n-1]的数组中查找x
//二分搜索
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int arr[] = { 23,24,25,26,27,28,29,30,34,35,36,38,42,56 };
	int k = 60;
	int left = 0, right = sizeof(arr) / sizeof(int), mid = 0;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("搜索完成,arr[%d]=k\n", mid);
			break;
		}
		if (left > right) 
		{
			printf("err:该数据找不到了\n");
		}
	}


	return 0;
}
//4、编写代码,演示多个字符从两端移动,向中间汇聚;演示字符串内容:get_busy_living_or_get_busy_dying_
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//4:两端渐变之中间打印字符
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>

int main()
{
	char str1[] = "get busy living or get busy dying";
	char str2[] = "#################################";
	int left = 0;
	//int right = (sizeof(str1) / sizeof(str1[1]) - 1)- 1;//除\0外实际元素的个数。sizeof(str1) / sizeof(str1[1])求字符串长度含\0
	int right = strlen(str1) - 1;//strlen()求字符串长度,不含\0,头文件:string.h

	for (; left <= right; left++, right--)
	{
		str2[left] = str1[left];
		str2[right] = str1[right];
		printf("%s",str2);
		Sleep(500);//延时
		system("cls");//清屏
		//Sleep()和system()的加入使得显示效果动态化
	}
	printf("%s", str2);

	return 0;
}

在这里插入图片描述

//5、编写代码实现,模拟用户登陆场景,并且只能登陆三次。(只允许输入三次密码,若密码正确提示登录成功,若三次均输入错误,退出程序)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

int main()
{
	char pswd[20] = { 0 };
	char k[] = "123456";

	int i = 3;
	do
	{
		printf("请输入密码:");
		scanf("%s", pswd);//密码:123456
		if (strcmp(pswd, k) != 0)
		{
			printf("密码错误\n");
			printf("请重新输入密码(剩余输入次数 = %d):", i-1);
			if (i - 1 == 0)
				printf("输入失败");

		}
		else
		{
			printf("密码正确\n");
			break;
		}
		i--;
	} while (i>0);

		return 0;
	}


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
例:猜数字游戏;
1、会自动生成1-100之间的一个随机数
2、猜数字
猜大:提示:猜大了,请重新猜数:
猜小:提示:猜小了,请重新猜数:
猜对:提示:恭喜,猜对了!
3、可以一直玩,除非退出游戏
采用模块化编程。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void menu()
{
	printf("***************************\n");
	printf("********1:开始游戏********\n");
	printf("********0:退出游戏********\n");
	printf("***************************\n");
}

void game()
{
	//1.产生1-100随机数
	//若仅有1,随循环次数每次生成的随机序列都是一致的
	int ret = 0;
	//srand((unsigned int)time(NULL));//定义rand()随机数的起点,仅需执行一次即可,若该处使用会使每次生成随机数非常临近
	ret = rand() % 100 + 1;//1-rand()生成1-32767之间的随机数,1-100:rand()%100+1
	//printf("%d ", ret);
	//2.猜数字
	int guess = 0;
	while(1)
	{
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了,请重新猜数:\n");
		}
		else if (guess < ret)
		{
			printf("猜小了,请重新猜数:\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}


int main()
{
	//进游戏就能玩,先执行再判断:do-while 
	int input = 0;
	srand((unsigned int)time(NULL));//定义rand()随机数的起点,输入参数不同,起点不同,仅需执行一次即可。time()时间戳,返回值类型为int
	do
	{
	menu();
	scanf("%d", &input);
	switch (input)
	{
	case 0:
		printf("退出游戏:");
		break;
	case 1:
		printf("开始游戏:");
		game();
		break;
	default:
		printf("输入错误,请重新出入:");
		break;
	}
	} while (input);

	return 0;
}

在这里插入图片描述
1、输入n个元素,将这些元素按照从大到小的顺序排列打印
冒泡排序:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//冒泡排序法
#define N 15

void menu()
{
	printf("***************************\n");
	printf("********1:开始排序********\n");
	printf("********0:退出排序********\n");
	printf("***************************\n");
}

void get_rank()
{
	int a[N] = { 0 };
	int i = 0;
	for (i = 0; i < N; i++)
	{
		scanf("%d", a + i);
	}//N元素一维数组生成

	for (int m = 0; m < N - 1; m++)
	{
		for (int n = 0; n < N - 1 - m; n++)
		{
			if (a[n] < a[n + 1])
			{
				int tmp = 0;
				tmp = a[n + 1];
				a[n + 1] = a[n];
				a[n] = tmp;
			}
		}
	}//冒泡排序
	
	for (int j = 0; j < N; j++)
	{
		printf("%d ", a[j]);
	}//排序结果输出
}

int main()
{
	int input = 0;
	do
	{
		printf("\n");
		menu();
		printf("输1开始,输0退出\n");
		scanf("%d", &input);

		switch (input)
		{
			case 0:
				printf("退出排序\n");
				break;
			case 1:
				printf("输入待排序数据\n");
				get_rank();
				break;
		}//switch完成菜单选项

	} while (input);

	return 0;
}

在这里插入图片描述
在这里插入图片描述
2、输入区间,打印该区间内所有3的倍数的数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

2、打印min - max(min、max可以输入设定)所有能被3整除的数

void menu()
{
	printf("***************************\n");
	printf("********1:开始************\n");
	printf("********0:退出************\n");
	printf("***************************\n");
}

void get_3_mult()
{
	int min = 0, max = 0;
	printf("确定数据区间,输入min max\n");
	scanf("%d%d", &min, &max);

	for (int m = min; m <= max; m++)
	{
			if (m % 3 == 0 && m != 0)
			{
				printf("%d ", m);
			}
	}
}

int main()
{
	int input = 0;
	do
	{
		printf("\n");
		menu();
		printf("输1开始,输0退出\n");
		scanf("%d", &input);

		switch (input)
		{
			case 0:
				printf("退出\n");
				break;
			case 1:
				printf("参数输入\n");
				get_3_mult();
				break;
		}

	} while (input);

	return 0;
}


3、任输1000-2000年之间的某一年,判断其是否为闰年。
闰年:
(1)四年一闰百年不闰:即如果year能够被4整除,但是不能被100整除,则year是闰年。
(2)每四百年再一闰:如果year能够被400整除,则year是闰年。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int year = 0;

void menu()
{
	//int year = 0;
	printf("请输入年份:\n");
	scanf("%d", &year);

	if (1000 >= year || 2000 <= year)
	{
		printf("请重新输入(年份1000~2000):\n");
	}
}

void get_year()
{
	if ((year % 4 == 0) && (year % 100) != 0)
	{
		printf("%d是普通闰年\n", year);
	}
	else if (year % 400 == 0)
	{
		printf("%d是世纪闰年\n", year);
	}
	else
	{
		printf("%d不是闰年\n",year);
	}
}

int main()
{
	int input = 0;
	do 
	{
		printf("输1开始,输0退出\n");
		scanf("%d", &input);

		switch (input)
		{
		case 0:
			printf("退出\n");
			break;
		case 1:
			menu();
			get_year();
			break;
		}
	} while (input);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sanch1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值