- 💂 个人主页: 程序员爱摸鱼
- 🤟 版权: 本文由【程序员爱摸鱼】原创、在CSDN首发、需要转载请联系博主
- 💬 如果文章对你有帮助、欢迎关注+点赞+收藏(一键三连)哦
- 💅 想寻找共同成长的小伙伴,可以互粉哦
💬文章目录
💅 输出
💅输入
💅位运算符
1. 基础语法
1.1 输出和输入
输出
- 输出:将程序的运行结果输出到控制台或终端窗口中
- printf语法格式
int printf (const char *format, ...);
- format参数是一个格式化字符串,包含了输出的格式控制信息
- 后面的参数
...
是可变参数,参数(要输出的数据)长度不固定
- 格式化占位符
打印格 式 | 对应数据类型 | 含义 |
%c | char | 字符型,输入的数字按照ASCII码相应转换为对应的字符 |
%hd | short int | 短整数 |
%hu | unsigned short | 无符号短整数 |
%d | int | 接受整数值并将它表示为有符号的十进制整数 |
%u | unsigned int | 无符号10进制整数 |
%ld | long | 接受长整数值并将它表示为有符号的十进制整数 |
%f | float | 单精度浮点数 |
%lf | double | 双精度浮点数 |
%e,%E | double | 科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写 |
%s | char * | 字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符) |
%p | void * | 以16进制形式输出指针 |
%o | unsigned int | 无符号8进制整数 |
%x,%X | unsigned int | 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF |
示例代码:
#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;
}
输入
- 输入:接收用户输入的数据的过程
- scanf语法格式
scanf("格式化字符串", &变量1, &变量2,...);
- 格式化字符串用于指定输入的数据类型及其格式
- 变量1、变量2等是要读入的变量的地址
示例代码:
#include <stdio.h>
int main() {
// 定义int类型变量age,通过scanf输入内容,然后打印内容
int age;
printf("请输入年龄:");
scanf("%d", &age);
printf("age = %d\n", age);
return 0;
}
案例
●从键盘输入一个圆形的半径,输出圆的周长和面积
●思路步骤
1.定义常量pi
2.定义半径变量r
3.输入半径
4.求周长和面积, * 为乘以运算符
5.输出周长和面积
示例代码:
#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.2 运算符
算术运算符
运算符 | 术语 | 示例 | 结果 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前自增 | a=2; b=++a; | a=3; b=3; |
++ | 后自增 | a=2; b=a++; | a=3; b=2; |
-- | 前自减 | a=2; b=--a; | a=1; b=1; |
-- | 后自减 | a=2; b=a--; | a=1; b=2; |
运行结果:
c1 = 2.000000
c2 = 2.500000
c3 = 2.500000
前置:b = 1, i = 1
后置:b = 0, i = 1
赋值运算符
运算符 | 术语 | 示例 | 结果 |
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; 等同于 a = a + 2; | a=2; |
-= | 减等于 | a=5; a-=3; 等同于 a = a - 3; | a=2; |
*= | 乘等于 | a=2; a*=2; 等同于 a = a * 2; | a=4; |
/= | 除等于 | a=4; a/=2; 等同于 a = a / 2; | a=2; |
%= | 模等于 | a=3; a%=2; 等同于 a = a % 2; | a=1; |
示例代码:
#include <stdio.h>
int main() {
int a = 10;
a += 5;
printf("a = %d\n", a);
return 0;
}
运行结果:
a = 15
比较运算符
C 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示。
运算符 | 术语 | 示例 | 结果 |
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
示例代码:
#include <stdio.h>
int main() {
int a = 10;
int b = 20;
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;
}
逻辑运算符
运算符 | 术语 | 示例 | 结果 |
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
示例代码:
#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");
return 0;
}
位运算符
运算符 | 术语 | 示例 | 结果 |
& | 按位与运算 | 011 & 101 | 2个都为1才为1,结果为001 |
| | 按位或运算 | 011 | 101 | 有1个为1就为1,结果为111 |
^ | 按位异或运算 | 011 ^ 101 | 不同的为1,结果为110 |
~ | 取反运算 | ~011 | 100 |
<< | 左移运算 | 1010 << 1 | 10100 |
>> | 右移运算 | 1010 >> 1 | 0101 |
ps:取反、左右位移运算需要在补码的基础上运算。
& -(与运算)
按位与(&)运算:位与位进行比较,如果都为1,则为1,否则为0;
/**
* 按位与(&)运算:位与位进行比较,如果都为1,则为1,否则为0;
* 示例:
* 40 & 15 = 8
* 0010 1000
* & 0000 1111
* -------------------
* 0000 1000
*/
printf("40 & 15 = %d\n", 40 & 15);
| -(或运算)
按位或(|)运算:位与位进行比较,如果都为0,则为0,否则为1;
/**
* 按位或(|)运算:位与位进行比较,如果都为0,则为0,否则为1;
* 示例:
* 40 | 15 = 47
* 0010 1000
* | 0000 1111
* ----------------
* 0010 1111
*/
printf("40 | 15 = %d\n", 40 | 15);
^ -(异或运算)
按位异或运算:位与位进行比较,相同为0,不同为1;
/**
* 按位异或运算:位与位进行比较,相同为0,不同为1;
* 示例:
* 40 ^ 15 = 39
* 0010 1000
* ^ 0000 1111
* ------------------
* 0010 0111
*/
printf("40 ^ 15 = %d\n", 40 ^ 15);
~ -(取反运算)
按位取反运算:补码取反,再将取反后的补码转为原码;
ps:无符号的数据,取反后最高位为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
*/
printf("~40 = %d\n", ~40);
printf("~15 = %d\n", ~15);
printf("~-15 = %d\n", ~(-15));
<< -(左移运算符)
将数字的二进制补码全部向左移动,空出来的位置补0,超出范围的二进制数丢弃;
有符号的数据左移后最高位如果为1,则需要进行逆运算;
注意事项:
- 无符号的数据,左移后最高位为1,也不需要逆运算;
- -128:1000 0000 特殊情况也不需要逆运算;
/**
* 示例:
* 40 << 4 = 0010 1000 << 4 = 1000 0000 = -128 (特殊的不需要逆运算)
* 41 << 4 = 0010 1001 << 4 = 1001 0000 = 1000 1111 = 1111 0000 = -112
* 7 6 5 4 3 2 1 0
* 1 0 0 1 0 0 0 0
*/
int8_t p = 40;
p <<= 4; // p = p << 4;
printf("40 << 4 = %d\n", p);
>> -(右移运算符)
将数字的二进制补码全部向右移动,空出来的位置补0,超出范围的二进制数丢弃;
/**
* 示例:
* 15 >> 4 = 0000 1111 >> 4 = 0000 0000 = 0
*
* 特殊情况,默认情况下计算机采用逻辑右移方式,即左侧空出来的位置补0,但如果是算术右移,那么左侧空出来的位置需要根据符号位的值来补位。
*
* -15 >> 2 = 1000 1111 >> 2 (原码)
* = 1111 0000 >> 2 (反码,注意:负数反码符号位不变)
* = 1111 0001 >> 2 (补码)
* = 1111 1100 (右移后的补码,注意:算术右移左侧空出来的位置需要根据符号位来补位)
* = 1111 1011 (右移后的反码,补码转反码只需-1即可)
* = 1000 0100 (右移后的原码)
* = -4
*/
int8_t q = 15;
q >>= 4;
printf("15 >> 4 = %d\n", q);
int8_t m = -15;
m >>= 2;
printf("-15 >> 2 = %d\n", m);
示例代码:
#include <stdio.h>
#include <inttypes.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;
}
运行结果:
案例需求:
// 将变量a的第2位设置为1,其他位保持不变
uint8_t a = 0b10110011; // 0xb3;
// 将变量b的第2位、第6位设置为1,其他位保持不变
uint8_t b = 0b10110011; // 0xb3;
// 将变量c的第5位设置为0,其他位保持不变
uint8_t c = 0b10110011; // 0xb3;
// 将变量d的第0~3位设置为0,其他位保持不变
uint8_t d = 0b11111111; // 0xff;
// 将变量e的第2位取反,其他位保持不变
uint8_t e = 0b10110011; // 0xb3;
// 将变量f取出8-15位
uint32_t f = 0x12345678;
示例代码:
#include <stdio.h>
#include <inttypes.h>
int main() {
// 将变量a的第2位设置为1,其他位保持不变
uint8_t a = 0b10110011; // 0xb3;
a |= (1 << 2); // 或者 x = x | (1 << 2);
printf("%02x\n", a); // b7, 10110111
// 将变量b的第2位、第6位设置为1,其他位保持不变
uint8_t b = 0b10110011; // 0xb3;
b |= (1 << 2 | 1 << 6);
printf("%02x\n", b); // f7,11110111
// 将变量c的第5位设置为0,其他位保持不变
uint8_t c = 0b10110011; // 0xb3;
c &= ~(1 << 5);
printf("%02x\n", c); // 93,10010011
// 将变量d的第0~3位设置为0,其他位保持不变
uint8_t d = 0b11111111; // 0xff;
d &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);
printf("%02x\n", d); // f0,11110000
// 将变量e的第2位取反,其他位保持不变
uint8_t e = 0b10110011; // 0xb3;
e ^= (1 << 2);
printf("%02x\n", e); // b7, 10110111
// 将变量f取出8-15位
uint32_t f = 0x12345678;
uint32_t temp = (f & 0x0000ff00) >> 8;
printf("%#x\n", temp);
return 0;
}
运算符优先级
- 不同的运算符默认具备不同的优先级,符号较多不用记,现用现查就可以。
- 当无法确定谁的优先级高时,加一个小括号就解决了。
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | -- |
() | 圆括号 | (表达式)/函数名(形参表) | -- | ||
. | 成员选择(对象) | 对象.成员名 | -- | ||
-> | 成员选择(指针) | 对象指针->成员名 | -- | ||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
~ | 按位取反运算符 | ~表达式 | |||
++ | 自增运算符 | ++变量名/变量名++ | |||
-- | 自减运算符 | --变量名/变量名-- | |||
* | 取值运算符 | *指针变量 | |||
& | 取地址运算符 | &变量名 | |||
! | 逻辑非运算符 | !表达式 | |||
(类型) | 强制类型转换 | (数据类型)表达式 | -- | ||
sizeof | 长度运算符 | sizeof(表达式) | -- | ||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | |||
% | 余数(取模) | 整型表达式%整型表达式 | |||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | |||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | |||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | |||
< | 小于 | 表达式<表达式 | |||
<= | 小于等于 | 表达式<=表达式 | |||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | |||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | -- |
/= | 除后赋值 | 变量/=表达式 | -- | ||
*= | 乘后赋值 | 变量*=表达式 | -- | ||
%= | 取模后赋值 | 变量%=表达式 | -- | ||
+= | 加后赋值 | 变量+=表达式 | -- | ||
-= | 减后赋值 | 变量-=表达式 | -- | ||
<<= | 左移后赋值 | 变量<<=表达式 | -- | ||
>>= | 右移后赋值 | 变量>>=表达式 | -- | ||
&= | 按位与后赋值 | 变量&=表达式 | -- | ||
^= | 按位异或后赋值 | 变量^=表达式 | -- | ||
|= | 按位或后赋值 | 变量|=表达式 | -- | ||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | -- |
想要了解更多吗?没时间解释了,快来点一点!!!
程序员爱摸鱼🐟
————————————————
版权声明:本文为CSDN博主「程序员爱摸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:程 序 员 爱 摸 鱼🐟