学习C语言第三天

2020/7/4
在C里, 想搬起石头砸自己的脚极为容易

进制和转换

存储知识

  • 回顾:计算机存储的最小单元为 内存单元 大小为1字节 = 8个二进制位。
  • 计算机只能使用2进制。
  • 10进制、8进制、16进制 是给人类使用,计算机不能使用。

2进制

  • 逢2进1,只有0和1

10进制转2进制

除2反向取余法
在这里插入图片描述

2转10

在这里插入图片描述

8进制

  • 程序中,用 0 开头 0123
  • 使用格式匹配符 %o、%#o
  • 每一位取值范围为:0–7

10转8 和 8转10

在这里插入图片描述

2转8

将二进制数,自右向左,每3位一组划分,不足3位的在前面填充0。每组使用 421转换

10111011101
10 111 011 101    
010 111 011 101 
 2   7   3   5
二进制数 :10111011101 对应的 8 进制为:02735  

1101001101
1 101 001 101
001 101 001 101 
对应的8进制数为:01515    

8转2

自左向右,将8进制数的每一位,按照 421的方式,展开为二进制

0167354
001 110 111 011 101 100
对应的二级制数为:1110111011101100  

057431
对应的二级制数为:101 111 100 011 001

16进制

  • 使用0x开头 0x123
  • 使用%x
  • 取值范围:0-9,a、b、c、d、e、f

16转2

2转16

将二进制数,自右向左,每4位分为一组,不足4位用0填充。每组使用 8421转换

1011011011110101101
101 1011 0111 1010 1101    
0101 1011 0111 1010 1101 
  5    b    7   A    d
对应的16进制: 0x5b7ad 
    
1111011011111011011000 1110 
0011 1101 1011 1110 1101 1000 1110  
对应的16进制:0x3dbed8e   

16转2

自左向右,将16进制数的每一位,按照 8421 的方式展开为2进制数

0x3Fc7e2
对应的二进制:0011 1111 1100 0111 1110 0010
  
0xa9dc4e
对应的二进制:1010 1001 1101 1100 0100 1110

小结

  • C程序中,使用频率 10进制>16进制>8进制
  • C程序中,不允许直接给变量用2进制赋值,也不能打印变量的二级制形式
int a = 123;		// 10进制赋初值
int b = 0123;		// 8进制赋初值
int c = 0x123;		// 16进制赋初值
int d = 101101; 	// 此数不是二进制数。会被编译器理解为10进制。
int e = 01101; 		// 此数不是二进制数。会被编译器理解为8进制。
  • 同一个数据,有不同的表现形式(10进制、8进制、16进制)
    在这里插入图片描述

输入输出函数

输入函数

  • printf函数结合 格式匹配符 输出
    • 已学过的格式匹配符
      • %d 有符号整型 int
      • %c 字符型 char
      • %x 16进制
      • %u 无符号整型 unsigned int
      • %f 单精度浮点型 float
      • %#x 16进制 带0x前缀
      • %ld 长整型 long
      • %lf 双精度浮点型 double
      • %llu 无符号长长整型 unsigned long long
      • %lld 有符号长长整型 long long
      • %lu 无符号长整型 unsigned long
      • %hhd char
      • %hhu unsigned char
      • %hd 短整型 short
      • %hu 无符号短整型 unsigned long
      • %o 8进制
      • %#o 8进制 带0前缀
  • putchar函数
    • 向屏幕输出一个字符
putchar('a'); == putchar(97); ---> 向屏幕输出一个字符 a
//只能输出一个字符,不是ASCII码,而是一个字符
putchar('\n'); 向屏幕输出一个换行符。
printf("\n"); 向屏幕输出一个换行符。

输入函数

  • getchar函数

    • 在程序运行期间,从键盘(标准输入stdin设备)动态获取用户输入的一个字符。
      • 将该字符对应的ASCII码返回
        在这里插入图片描述
  • scanf函数

    • 在程序运行期间,结合格式匹配符,动态获取用户键盘数据,保存到变量中
    • 注意:
      1. 格式匹配串中,不能随意添加\n
      2. 与格式匹配符对应的变量,加&
      3. 不想看到scanf出的警告
        • 用变量接收scanf的返回值
        • 用void强制转换
  • 获取一个整数

int main(void)
{
	int a = 10;  // 定义变量a, 用来存储 键盘获取的 整型数据。

	// scanf函数的格式匹配串中,不能随意添加 \n
	// int ret = scanf("%d", &a);   // &a 代表 a变量的内存空间。 用来存储变量值。
	// int ret 作用: 接收scanf返回值,防止出现警告。

	(void)scanf("%d", &a);  // 会覆盖a的原值。
	// (void) 作用: 将 scanf 函数的返回值,强转为 空。 防止出现警告。

	printf("scanf接收的变量值为:%d\n", a);

	system("pause");
	return EXIT_SUCCESS;
}
  • 获取多个整数
    在这里插入图片描述
  • 获取字符
    在这里插入图片描述

C4996报错

  • VS中,默认 scanf 函数不能使用,会报错 C4996。
  • 在.c 第一行添加 #define _CRT_SECURE_NO_WARNINGS 宏,解决此错误!!
    在这里插入图片描述

运算符

运算符类型作用
算术运算符用于处理四则运算
赋值运算符用于将表达式的值赋给变量
比较运算符用于表达式的比较,并返回一个真值或假值
逻辑运算符用于根据表达式的值返回真值或假值
逗号运算符用于实现逗号表达式
三目运算符用于实现三目运算
sizeof运算符用于求字节数长度

算数运算符

  • 先乘除取余,后加减。 (* / % + -)
  • 整数的除法运算,得到结果赋值给 int 变量,只取整数部分。int m = 39 / 10; ----> 3
  • 除0不允许。printf("%d\n", 39 / 0);
  • 对0取余不允许。printf("%d\n", 39 % 0);
  • 不允许对小数取余。printf("%d\n", 39 % 3.4);
  • 对负数取余,结果为余数的绝对值。printf("%d\n", 39 % -5); —> 4
  • 取余运算:
    在这里插入图片描述

赋值运算符

  • = 赋值运算符,也叫单向赋值运算符。右边 赋值给 左边。
  • += 加等于。a += 5 等价于 a = a + 5;
  • -= 减等于。a -= 5 等价于 a = a - 5;
  • *= 乘等于。 a *= 5 等价于 a = a * 5;
  • /= 除等于。a /= 5 等价于 a = a / 5;
  • %= 取余等于。a %= 5 等价于 a = a % 5;

—— 所有赋值运算符,都是带有 副作用 的运算。运算结束后变量值会被修改。

自增自减运算符

  • 自减、自减运算符,都是带有副作用的运算符。
int a = 10;
a += 1;  	// 等价于 
a = a + 1;	// 等价于 
a++;		// 等价于 
++a;

int b = 8;
b -= 1; 	// 等价于 
b = b-1;	// 等价于
b--;		// 等价于 
--b;		// 等价于 
  • 前缀自增 —— 先自增,再取值。
int a = 10;
int b = ++a;
printf("b = %d\n", b);   // b = 11
printf("a = %d\n", a);   // a自增完成,变为 11

int c = 20;
printf("++c = %d\n", ++c);  // ++c = 21
  • 后缀自增 —— 先取值,再自增。
int a = 10;
int b = a++;  // 先将a值取出给b赋值,再增1 
printf("b = %d\n", b);   // b = 10;
printf("a = %d\n", a);   // a = 11;

int c = 20;
printf("c++ = %d\n", c++);  // 先将c的值取出,匹配给 %d, c再增1
printf("c = %d\n", c);		// 上面完成了自增,c = 21

比较运算符

  • 含有比较运算符的算式,运算后的结果只有两种:
    • 成立:真 —— 1
    • 不成立:假 —— 0
运算符术语示例结果
==相等于4 == 30
!=不等于4 != 31
<小于4 < 30
>大于4 > 31
<=小于等于4 <= 30
>=大于等于4 >= 11
  • 计算机中 判等 使用的 ==, 不使用 =*

  • 数学运算中的 : 13 < var < 16 。 在程序中,不能这么使用。改写成 逻辑运算。var > 13 && var < 16
    在这里插入图片描述

逻辑运算符

  • 通常用作,将多个比较表达式连接在一起,形成一个表达式。
    • 0:为假
    • 非0:为真。( 1为真、-34为真、4.5676为真 )
运算符术语示例结果
!!a若a为假,则!a为真;若a为真,则!a为假。
&&a && b若a和b都为真,则结果为真,否则为假。
||a || b若a和b有一个为真,则结果为真,二者同为假,结果为假。
  • 逻辑运算符使用 8字箴言:
    • 逻辑非:
      • 非真为假,非假为真。
        在这里插入图片描述
  • 逻辑与(并且)
    • 同真为真,其余为假。
      在这里插入图片描述
  • 逻辑或(或)
    • 有真为真,同假为假。
      在这里插入图片描述

短路运算

  • 当有多个表达式时,若左边的表达式的值,足矣确定越算结果,则右边的表达式不计算。
    在这里插入图片描述
    在这里插入图片描述

逗号运算符

  • 含有 “,” 运算符的表达式,称之为 逗号表达式。整个逗号表达式运算结果,取最后一个子表达式结果。
// 逗号运算符
int main(void)
{
	int x, y, z;

	int a = (x = 1, z = 3, y = 2);

	printf("a = %d\n", a);  // a = 2

	return 0;
}

三目运算符

语法:表达式1 ?表达式2 :表达式3

  • 表达式1,通常是一个判别表达式。(或者当成判别表达式用
    • 表达式1判别结果为 真:
      • 整个三目运算取 表达式2的值。
    • 表达式1判别结果为 假:
      • 整个三目运算取 表达式3的值。
        在这里插入图片描述
  • 注意:三目运算语法允许嵌套。但是!在编程时,不推荐使用。—— 极大的影响代码可读性。

运算符优先级

[]、() > 负号、自增自减、强转、逻辑非、sizeof、*、& > 算数运算符(先乘除取余,后加减) > 比较运算符 > 逻辑运算符 > 三目运算符 > 赋值运算符 > 逗号运算符

在这里插入图片描述

if 分支语句

用来实现模糊匹配。 用来匹配一定的数据范围。

  • if … else 分支
int main(void)
{
	int var;

	printf("请输入一个整数:");

	(void)scanf("%d", &var);

	if (var > 0)
	{
		printf("var > 0\n");
	}
	else
	{
		printf("var <= 0\n");
	}

	return 0;
}
  • if … else if … else if … else if … else
// 语法:
if (判别表达式1)			// 此处不能添加;
{
    判别表达式1成立(为真),执行的代码。
}
else if (判别表达式2)	// 此处不能添加;
{
     判别表达式1不成立(为假), 判别表达式2成立(为真),执行的代码。
}
else if (判别表达式3)	// 此处不能添加;
{
    判别表达式12均不成立(为假), 判别表达式3成立(为真),执行的代码。
}
。。。
else
{
	以上所有判别表达式都为假。 执行的代码。
}


// 输入学生成绩,打印优良可差。90+优秀、70-90良好、60+可以、60- 不及格
int main(void)
{
	int score; // 代表学生成绩

	printf("请输入学生成绩:");

	(void)scanf("%d", &score);

	if (score >= 90)
	{
		printf("优秀!\n");
	}
	else if (score >= 70 && score < 90)
	{
		printf("良好!\n");
	}
	else if (score >= 60 && score < 70)
	{
		printf("及格\n");
	}
	else
	{
		printf("不及格\n");
	}

	system("pause");
	return EXIT_SUCCESS;
}

switch 分支语句

  • 用来实现精确匹配。匹配具体的一个数值。不能直接用来判断区间。
// 基本语法。
switch (匹配表达式)
{
        case 常量1:
            执行语句1;
        	break;			// 结束当前 switch 分支,防止 case 穿透。
        case 常量2:
            执行语句2;
        	break;			// 结束当前 switch 分支,防止 case 穿透。
        case 常量3:
            执行语句3;
        	break;			// 结束当前 switch 分支,防止 case 穿透。
        。。。
        case 常量N:
            执行语句N;
        	break;			// 结束当前 switch 分支,防止 case 穿透。
        default:
            上述所有 case 都不满足的其他情况。
            break;
}

使用 switch 语句实现 :打印学生成绩 优良可差。

int main(void)
{
	int score; // 代表学生成绩

	printf("请输入学生成绩:");

	(void)scanf("%d", &score);

	switch (score/10)   // 确定具体的匹配数据。
	{
	case 10:	// 做具体匹配
		printf("优秀!\n");
		break;
	case 9:		// 做具体匹配
		printf("优秀!\n");
		break;
	case 8:		// 做具体匹配
		printf("良好!\n");
		break;
	case 7:
		printf("良好!\n");
		break;
	case 6:
		printf("可以!\n");
		break;
	default:
		printf("差劲\n");
		break;
	}

	return EXIT_SUCCESS;
}

case 穿透

  • 一个case分支,如果没有 break 关键字。 那么它会继续向下执行下一个 case 分支。这叫做:case 穿透。
  • 实际编程中,case 穿透可以加以利用。
// 输入学生成绩,打印优良可差。90+优秀、70-90良好、60+可以、60- 不及格
int main(void)
{
	int score; // 代表学生成绩

	printf("请输入学生成绩:");

	(void)scanf("%d", &score);

	switch (score/10)
	{
	case 10:			// 没有break,会发送case穿透。
	case 9:
		printf("优秀!\n");
		break;
	case 8:				// 没有break,会发送case穿透。
	case 7:
		printf("良好!\n");
		break;
	case 6:
		printf("可以!\n");
		break;
	default:
		printf("差劲\n");
		break;
	}

	return EXIT_SUCCESS;
}

编程练习

1.进制转换

(1)写出 16进制 数 0xc5af 对应的二进制数。

(2)写出 2进制 数 110101001 对应的10进制数 和 16进制数。

//0x5af
//010110101111

//1 1010 1001
//425
//0x1a9

2.已知3个整数 a、b、c, 使用 三目运算 或 if语句 找出 3个数中的最小值。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int a, b, c;
	//三目运算
	printf("请输入三个整数a,b,c:\n");
	(void)scanf("%d %d %d",&a,&b,&c);
	int min;
	min = b < c ? b : c;
	min = a < min  ? a : min;
	printf("三个数中的最小值为:%d\n",min);
	return 0;
}

3.接收用户输入一个数字作为年份,判断是否为闰年。提示:能被4整除,且不能被100整除为闰年。能被400整除也为闰年。

  • 示例:1900 不是闰年。 2000 年是闰年。 2004 年是闰年。
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	unsigned int year;
	printf("请输入一个年份:\n");
	(void)scanf("%u",&year);
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
	{
		printf("%u年是闰年\n",year);
	}
	else
	{
		printf("%u年不是闰年\n",year);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值