目录
8.条件操作符(三目操作符)
单目操作符: !a这些
双目操作符:a+b这些
exp1 ? exp2 : exp3(exp1为真,exp2就计算,exp3不计算
exp1为假,exp2就不计算,exp3计算)
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
if (a > 5)
{
b = 3;
}
else
b = -3;
/*(a > 5) ? (b = 3) : (b = -3);*/
b = (a > 5) ? 3 : -3;
return 0;
}
9.逗号表达式
exp1,exp2,exp3,...expN
逗号表达式:从左向右计算,整个表达式结果是最后一个表达式的结果!
逗号表达式有时能帮我们简化代码
10.下标引用,函数调用操作符
//int main()
//{
// int arr[10] = { 1,2,3,4,5 };
// // 0 1 2 3 4 5 6 7 8 9
// //数组的起始是有下标的,下标是0开始的
// printf("%d\n", arr[2]);//[] 下标引用操作符,arr 和 2 是[] 的两个操作数
// //3 + 5
// //
// return 0;
//}
//#include <string.h>
//
//int Add(int x, int y)
//{
// return x + y;
//}
//
//void test()
//{
// printf("hehe\n");
//}
//int main()
//{
// //int len = strlen("abc");//() 函数调用操作符
// //() 的操作数是:strlen "abc"
// //printf("%d\n", len);
//
// int c = Add(3, 5);//() 函数调用操作符
// //Add 3 5
// //对于函数调用操作符来说,最少有1个操作数
//
// printf("%d\n", c);
//
// test();
// return 0;
//}
11.结构体
结构体 - 复杂类型
- 自定义类型
这些都是内置类型
但是运用结构体,我们可以自定义类型
比如我们要描述一本书,我们需要书名,作者,出版社,定价,书类和书号等等,我们就可以用结构体定义一个书的类型
struct Book
{
char name[30];//成员
char author[20];
float price;
};
void Print(struct Book* p)
{
/*printf("%s %s %.1f\n", (*p).name, (*p).author, (*p).price);*/
printf("%s %s %.1f\n", p->name, p->author, p->price);
//结构指针->成员
}
int main()
{
struct Book b1 = {"C语言第一课", "鹏哥", 66.5f};//书
struct Book b2 = {"数据结构第一课", "杭哥", 88.6f};//书
Print(&b1);
Print(&b2);
//printf("%s %s %.1f\n", b1.name, b1.author, b1.price);
//printf("%s %s %.1f\n", b2.name, b2.author, b2.price);
//结构体变量.成员名
return 0;
}
12.表达式求值
1. 表达式在计算过程中,有哪些类型转换?
2. 表达式的求值顺序是什么?
类型转换
1.整体提升(隐式发生)
C语言的整形算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换成为普通整型,这种转换称为整型提升。
int main()
{
char c1 = 5;
char c2 = 127;
char c3 = c1 + c2;
printf("%d\n", c3);
return 0;
}
上面这个程序打印结果是啥呢,132?那你就想的太简单了,正确结果是-124
为什么是-124呢,请看代码详解
int main()
{
char c1 = 5;
//00000000000000000000000000000101
// 因为char最多能存放1个字节(8个bit位),所以只能截断高位
//00000101 - c1
char c2 = 127;
//01111111111111111111111111111111
//01111111 - c2
char c3 = c1 + c2;
//先进行整型提升,把原来的两个00000101和01111111进行高位补充
//00000000000000000000000000000101
//00000000000000000000000001111111
//00000000000000000000000010000100
//10000100 - c3
//%d - 10进制的形式打印有符号的整数
//10000100 整型提升:11111111111111111111111110000100 - 补码
//11111111111111111111111110000011 - 反码
//10000000000000000000000001111100 --> -124
printf("%d\n", c3);
return 0;
}
再看一个例子
//%u - 10进制的形式打印无符号的整数
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));
return 0;
}
这个打印结果是什么呢?
答案是 注意上面所说的整型提升针对的是表达式,+c 和 -c都是表达式,经过整型提升后变成int(4个字节)
2.算术转换
float f = 3.14f
int n = 10;
n + f ;//程序会先把n转换成float形式再相加,这个是算术转换的一个例子
3.算术表达式求值顺序
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | -- |
() | 圆括号 | (表达式)/函数名(形参表) | -- | ||
. | 成员选择(对象) | 对象.成员名 | -- | ||
-> | 成员选择(指针) | 对象指针->成员名 | -- | ||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
~ | 按位取反运算符 | ~表达式 | |||
++ | 自增运算符 | ++变量名/变量名++ | |||
-- | 自减运算符 | --变量名/变量名-- | |||
* | 取值运算符 | *指针变量 | |||
& | 取地址运算符 | &变量名 | |||
! | 逻辑非运算符 | !表达式 | |||
(类型) | 强制类型转换 | (数据类型)表达式 | -- | ||
sizeof | 长度运算符 | sizeof(表达式) | -- | ||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | |||
% | 余数(取模) | 整型表达式%整型表达式 | |||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | |||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | |||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | |||
< | 小于 | 表达式<表达式 | |||
<= | 小于等于 | 表达式<=表达式 | |||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | |||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | -- |
/= | 除后赋值 | 变量/=表达式 | -- | ||
*= | 乘后赋值 | 变量*=表达式 | -- | ||
%= | 取模后赋值 | 变量%=表达式 | -- | ||
+= | 加后赋值 | 变量+=表达式 | -- | ||
-= | 减后赋值 | 变量-=表达式 | -- | ||
<<= | 左移后赋值 | 变量<<=表达式 | -- | ||
>>= | 右移后赋值 | 变量>>=表达式 | -- | ||
&= | 按位与后赋值 | 变量&=表达式 | -- | ||
^= | 按位异或后赋值 | 变量^=表达式 | -- | ||
|= | 按位或后赋值 | 变量|=表达式 | -- | ||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | -- |
但是有一些表达式就算有优先级也有结合性,但是在不同编译器里面的计算结果也会出现不同
这是VS2022的计算结果
这是VScode的计算结果