- 个人主页: 程序员爱摸鱼
- 版权: 本文由【程序员爱摸鱼】原创、在CSDN首发、需要转载请联系博主
- 如果文章对你有帮助、欢迎关注+点赞+收藏(一键三连)哦
- 想寻找共同成长的小伙伴,可以互粉哦
1. 基础语法
1.1 输出和输入
输出
输入
1.2 运算符
算术运算符
赋值运算符
比较运算符
逻辑运算符
位运算符
& -(与运算)
| -(或运算)
^ -(异或运算)
~ -(取反运算)
<< -(左移运算符)
>> -(右移运算符)
运算符优先级
int printf (const char *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
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("格式化字符串", &变量1, &变量2,...);
示例代码:
#include
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
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;
}
运行结果图:
运算符 |
术语 |
示例 |
结果 |
+ |
加 |
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
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
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
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,则需要进行逆运算;
注意事项:
/**
* 示例:
* 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
#include
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
#include
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版权协议,转载请附上原文出处链接及本声明。
原文链接:程 序 员 爱 摸 鱼