C语言基础学习DAY3

一、输入和输出

1.输出

        (1)输出定义:将程序的运行结果输出到控制台或终端窗口中

        (2)printf语法格式如下:

int a;
a=10;
printf("%d\n",a);

        (3)printf常用的格式化占位符

占位符对应类型示例输出说明
%dint123十进制有符号整数
%uunsigned int123十进制无符号整数
%hdshort / short int123short整数
%huunsigned short123无符号short
%ldlong123456long整数
%luunsigned long123456无符号long
%lldlong long123456789超大整数
%lluunsigned long long123456789无符号超大整数
%ccharA单个字符
%s字符串 char[]hello字符串
%ffloat3.14浮点数输出
%lfdouble3.14double输入常用
%x十六进制整数ff十六进制(小写)
%X十六进制整数FF十六进制(大写)
%o八进制整数77八进制
%p指针/地址0x1234内存地址

        (4)printf常用的格式化占位符示例代码

#include <stdio.h>

int main() {
	// 定义变量
	char c = 'A';
	short s = 10;
	int i = 10;
	long l = 10;
	float f = 1.123456789123456789;
	double d = 1.123456789123456789;
	unsigned int ui = 20;
	char *name = "bill";
	
	// 格式化输出
	// 整型
	printf("c=%d\n", c);
	printf("s=%hd\n", s);
	printf("i=%d\n", i);
	printf("l=%ld\n", l);
	// 浮点类型
	printf("f=%.10f\n", f);
	printf("d=%.20lf\n", d);
	// 无符号数据
	printf("u=%u\n", ui);
	// 八进制和十六进制 可以加上前缀# 自动输出八进制和十六进制0或0x
	printf("o=%#o\n", 120);
	printf("x=%#x\n", 120);
	// 字符串类型
	printf("s=%s\n", name);
	// 内存地址
	printf("ps=%p\n", &s);
	
	return 0;
}

2.输入

        (1)输入:接受用户输入数据的过程

        (2)scanf语法格式

scanf("格式化字符串",&变量一,&变量二,......);

(格式化字符串用于指定输入的数据类型及其格式,变量1、变量2等是要读入的变量的地址)

        (3)示例代码

#include <stdio.h>

int main() {
	//定义int类型变量age,通过scanf输入内容,然后打印内容
	int age;
	printf("请输入年龄:");
	scanf("%d",&age);
	printf("age =%d\n",age);
	return 0;
}

3.例题

        (1)从键盘输入一个圆形半径,输出圆的周长和面积

       (2) 思路步骤

1. 定义常量pi
2. 定义半径变量r
3. 输入半径
4. 求周长和面积, * 为乘以运算符
5. 输出周长和面积

        (3)参考代码

#include <stdio.h>

int main() {
	// 1.定义常量pi
	const double pi = 3.1415;
	// 2.定义半径变量r
	double r;
	// 3.输入半径
	printf("请输入半径:");
	scanf("%lf", &r);
	// 4.求周长和面积, * 为乘以运算符
	double len = 2 * pi * r;
	double area = pi * r * r;
	// 5.输出周长和面积
	printf("周长len = %lf, 面积area = %lf\n", len, area);
	
	return 0;
}

二、运算符

1.算术运算符

运算符描述示例结果说明
+加法a + b13双目运算符
-减法a - b7双目运算符
*乘法a * b30双目运算符
/除法a / b3整数除法截断小数;若为浮点数 10.0/3 → 3.333333
%取模(求余)a % b1只能用于整数,结果的符号与被除数相同
++自增1a++ 或 ++a11单目运算符,分前置(先增减后使用)和后置(先使用后增减)
--自减1b-- 或 --b2单目运算符,同上

代码示例

#include <stdio.h>

int main() {
    // 2数相除,要想得到小数的结果,分子分母必须有一个数是小数
    double c = 5/2; // 5, 2个都是整数,只会取整
    printf("c1 = %lf\n", c);

    c = 5.0/2; 
    printf("c2 = %lf\n", c);

    c = 5/2.0; 
    printf("c3 = %lf\n", c);

    int i = 0;
    // 前置++
    // 先加后用
    int b = ++i; 
    printf("前置:b = %d, i = %d\n", b, i);

    // 后置++
    // 先用后加
    i = 0;
    b = i++;
    printf("后置:b = %d, i = %d\n", b, i);

    return 0;
}

2.赋值运算符

运算符名称示例等价写法作用说明
=赋值运算符a = 5把右边的值赋给左边变量
+=加后赋值a += 3a = a + 3先相加,再赋值
-=减后赋值a -= 2a = a - 2先相减,再赋值
*=乘后赋值a *= 4a = a * 4先相乘,再赋值
/=除后赋值a /= 2a = a / 2先相除,再赋值
%=取模后赋值a %= 3a = a % 3取余数后赋值
<<=左移后赋值a <<= 1a = a << 1左移位后赋值
>>=右移后赋值a >>= 1a = a >> 1右移位后赋值
&=按位与后赋值a &= ba = a & b按位与后赋值
|=按位或后赋值a |= ba = a | b按位或后赋值
^=按位异或后赋值a ^= ba = a ^ b按位异或后赋值

代码示例:

#include <stdio.h>

int main() {
	int a=20;
	a -= 5;
	printf("%d\n",a);
	return 0;
}

3.比较运算符

        C 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示。且一个=代表赋值。

运算符名称示例含义结果
==等于a == b判断 a 是否等于 b相等为 1,否则为 0
!=不等于a != b判断 a 是否不等于 b成立为 1,否则为 0
>大于a > b判断 a 是否大于 b成立为 1,否则为 0
<小于a < b判断 a 是否小于 b成立为 1,否则为 0
>=大于等于a >= b判断 a 是否大于或等于 b成立为 1,否则为 0
<=小于等于a <= b判断 a 是否小于或等于 b成立为 1,否则为 0

代码示例:

#include <stdio.h>

int main() {
	int a = 15;
	int b = 30;
	printf("%d\n", a == b);
	printf("%d\n", a != b);
	printf("%d\n", a > b);
	printf("%d\n", a < b);
	printf("%d\n", a >= b);
	printf("%d\n", a <= b);
	return 0;
}

4.逻辑运算符

运算符名称示例含义结果规则
&&逻辑与a > 0 && b > 0两个条件都成立都为真结果才为 1
||逻辑或a > 0 || b > 0两个条件任意一个成立有一个真结果就为 1
!逻辑非!(a > 0)条件取反真变假,假变真

代码示例:

#include <stdio.h>

int main() {

	// &&(与),可以理解为并且
	// 案例:请判断班长和他女朋友是否符合法定结婚年龄
	int boy = 25;
	int girl = 21;
	int result = boy >= 22 && girl >= 20;
	printf("%d\n", result);

	// ||(或),可以理解为或者
	// 案例:班长女朋友玩原神没有原石了,请帮班长判断是否有足够的钱
	double wx_money = 100;
	double alipay_money = 300;
	result = wx_money >= 398 || alipay_money >= 398 || wx_money + alipay_money >= 398;
	printf("%d\n", result);

	// !(非),可以理解为不是
	printf("%d\n", !0);
	printf("%d\n", !!1);

	// 短路规则
	// && 左边为假,右边不执行
	// && 左边为真,右边执行
	0 && printf("我是右边不执行\n");
	1 && printf("我是右边不执行\n");
	// || 左边为真,右边不执行
	// || 左边为假,右边执行
	1 || printf("我是右边不执行\n");
	0 || printf("我是右边不执行\n");
	return 0;
}

5.位运算符

运算符名称作用说明示例二进制运算过程结果
&按位与两个位都为1,结果才为15 & 30101 & 0011 = 00011
|按位或两个位有一个为1,结果就为15 | 30101 | 0011 = 01117
^按位异或两个位不同为1,相同为05 ^ 30101 ^ 0011 = 01106
~按位取反0变1,1变0~5~00000101 = 11111010-6
<<左移所有二进制位左移,右边补05 << 10101 → 101010
>>右移所有二进制位右移5 >> 10101 → 00102

        (补充:取反、左移、右移都要在补码的基础上运算)

(1)与运算(&)

        按位与(&)运算:位与位进行比较,如果都为1,则为1,否则为0

                                    (口诀:全一为一,其余为零)

代码示例:

/*
	40与15进行与运算
	40转换成二进制为 0010 1000;
	15转换成二进制为 0000 1111;
	进行与运算:0010 1000
			  & 0000 1111
            ------------------
				0000 1000 -> 8
*/
#include <stdio.h>

int main() {
	printf("40 & 15 = %d\n", 40 & 15);
	return 0;
}

(2)或运算(|)

        按位或(|)运算:位与位进行比较,如果都为0,则为0,否则全为1

                                      口诀:全零为零,其余为一

/*
40与15进行与运算
40转换成二进制为 0010 1000;
15转换成二进制为 0000 1111;
进行与运算:0010 1000
		  | 0000 1111
		------------------
			0010 1111 -> 47
*/
#include <stdio.h>

int main() {
	printf("40 | 15 = %d\n", 40 | 15);
	return 0;
}

(3)异或运算(^)

        按位异或运算:位与位进行比较,不同为1,相同为0;

        口诀:不同为一,相同为零。

代码示例:

/*
40与15进行与运算
40转换成二进制为 0010 1000;
15转换成二进制为 0000 1111;
进行与运算:0010 1000
		  ^ 0000 1111
		------------------
			0010 0111 -> 39
*/
#include <stdio.h>

int main() {
	printf("40 ^ 15 = %d\n", 40 ^ 15);
	return 0;
}

(4)取反运算(~)

      按位取反运算:补码取反,再将取反后的补码转为原码;

      补充:无符号的数据,取反后最高位为1,也不需要逆运算。

/**
 * 按位取反运算:补码取反,再将取反后的补码转为原码。
 *      1、正数取反:由于正数的原码和补码是相同的,取反的方式简便了些。
 *              补码(原码) -> 取反 -> 补码逆运算 -> 反码逆运算(符号位不变) -> 取反后的原码
 *      2、负数取反:
 *              原码 -> 反码 -> 补码 -> 取反 -> 取反后的补码即原码
 * 示例:
 *            原码(补码)  取反的补码   补码逆运算-1  反码逆运算
 *      ~40 = 0010 1000 -> 1101 0111 -> 1101 0110 -> 1010 1001 = -41
 *
 *            原码(补码)  取反的补码   补码逆运算-1  反码逆运算
 *      ~15 = 0000 1111 -> 1111 0000 -> 1110 1111 -> 1001 0000 = -16
 *
 *                原码         反码          补码          取反
 *      ~-15 = 1000 1111 -> 1111 0000 -> 1111 0001 -> 0000 1110 = 14
 */
#include <stdio.h>

int main() {
	printf("~40 = %d\n", ~40);
	printf("~15 = %d\n", ~15);
	printf("~-15 = %d\n", ~(-15));
	return 0;
}

(5)左移运算符(<<)

        规则:将数字的二进制补码整体左移,左边超出部分丢弃,右边空位补0

        注意事项:

  • 有符号数:左移后若最高位为 1,表示负数,结果是补码形式(有时称“逆运算”即补码还原)
  • 无符号数:左移后最高位为 1不用处理
  • 特殊值 -128:左移后最高位为 1也不用处理

代码示例:

#include <stdio.h>

int main() {
	/**
	 * 示例:
	 *      40 << 4 = 0010 1000 << 4 = 1000 0000 = -128 (特殊的不需要逆运算)
	 *      41 << 4 = 0010 1001 << 4 = 1001 0000 = 1000 1111 = 1111 0000 = -112
	 */
	
	int8_t p = 40;
	int8_t X = 41;
	p <<= 4; //  p = p << 4;
	X <<= 4; //  p = p << 4;
	printf("40 << 4 = %d\n", p);
	printf("41 << 4 = %d\n", X);
	return 0;
}

(6)右移运算符(>>)

        规则:将数字的二进制补码整体右移,右边超出部分丢弃,左边空位补符号位(原最高位)

        注意事项:

  • 正数:左边空位补0
  • 负数:左边空位补1
  • 负数右移结果属于实现定义,不同编译器可能不同
  • 移动位数不能为负或超过类型长度

代码示例:

#include <stdio.h>

int main() {


	/*
	23:
	0001 0111【原码】
	0001 0111【反码】
	0001 0111【补码】 >> 2
	-----------------
	0000 0101【补码】 --->  5
	*/
	printf(" 23 >> 2 = %d \n", 23 >> 2) ;


	/*
	-23:
	1001 0111【原码】
	1110 1000【反码】
	1110 1001【补码】 >> 2
	-----------------------------------------------
	1111 1010【补码】 ->  1111 1001【反码】-> 1000 0110 【原码】 ==> -6
	*/
	printf(" -23 >> 2 = %d \n", -23 >> 2) ;
	
	return 0;
}

(7)总结

综合代码示例:

#include <stdio.h>
#include <stdint.h>

int main() {
	uint8_t a = 3;          // 0000 0011
	uint8_t b = 10;         // 0000 1010
	// 打印显示2个字符,个数不够,左边补0
	printf("%02x\n", a & b); // 0000 0010,16进制为02
	printf("%02x\n", a | b); // 0000 1011,16进制为0b
	printf("%02x\n", a ^ b); // 0000 1001,16进制为09

	uint8_t c = 10;          // 0000 1010
	uint8_t temp = ~c;       // 1111 0101
	printf("%02x\n", temp);   // 1111 0101,16进制为f5
	printf("%02x\n", c << 1); // 0001 0100,16进制为14
	printf("%02x\n", c >> 1); // 0000 0101,16进制为05

	return 0;
}

三、位运算——寄存器操作

1、第N位置1: a |= (1 << N)

拆解:(1 << N)

(1)把数字1左移N位

(2)得到的结果为只有第N位是1,其余为0的数;

例如:N=3 得到的结果为: 1 << 3    -> 0000 1000

a | =

(1)表示按位或然后赋值(全零为零,其余为一)

(2)规则:只要某位有1,结果该位就是1

例如:

int a = 5;      // 0101
a |= (1 << 3);
                 0000 0101
               | 0000 1000
              -------------------
				 0000 1101 -> 把第三位成功置1;

2、把第N位清0:a &= ~(1 << N)

拆解:(1 << N)

(1)把数字1左移N位

(2)得到的结果为只有第N位是1,其余为0的数;

        ~(1 << N)

(1)按位取反

(2)第N位变为0,其余变为1

例如:

1<<2       0000 0100
~(1<<2)    1111 1011

         a &= ...

(1)表示按位与然后赋值(全一为一,其余为零)

(2)规则:只要某位有0,结果该位就是0;

例如:

int a = 7;      // 0111
a &= ~(1 << 1); 
  1 << 1     0000 0010
~(1 << 1)    1111 1101
           & 0000 0111
        ------------------
             0000 0101 -> 把第一位成功清0;

 四、运算符优先级

  优先级表格图片

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值