宁波网站建设费用,小型创业项目,网站面板,镇江市建设工程网站【C语言】——详解操作符#xff08;下#xff09; 前言七、关系操作符八、逻辑操作符8.1、 与运算符8.2、 | 或运算符 九、条件操作符十、逗号表达式十一、下标引用与函数调用操作符11.1、[ ] 下标引用操作符11.2、( ) 函数调用操作符 十二、 结构成员操作符12.1、… 【C语言】——详解操作符下 前言七、关系操作符八、逻辑操作符8.1、 与运算符8.2、 | 或运算符 九、条件操作符十、逗号表达式十一、下标引用与函数调用操作符11.1、[ ] 下标引用操作符11.2、( ) 函数调用操作符 十二、 结构成员操作符12.1、结构体12.2、结构体成员访问操作符 十三、操作符的属性优先级、结合性13.1、优先级13.2、结合性 十四、表达式求值14.1、整型提升14.2、算术转换 前言 操作符的分类
算数操作符 、 - 、* 、/ 、%位移操作符 、 位操作符 、 | 、^ 、 ~赋值操作符 、 、 - 、 * 、 / 、 % 、 、 、 、 | 、 ^单目操作符 、 、 -- 、 、 * 、 、 - 、 ~ 、 sizeof 、类型关系操作符 、 、 、 、 、!逻辑操作符 、 ||、条件操作符 、:逗号表达式下标引用 [ ]函数调用 ( )结构成员访问 . 、- 上一章【C语言】——详解操作符上中我给大家详细讲解了前五种操作符接下来让我们继续把剩下的操作符学完吧。
七、关系操作符 大于操作符 小于于操作符 大于等于操作符 小于等于操作符 相等操作符 不相等操作符 ! 关系表达式通常返回 0 或 1表示真假。 关系表达式通常用于 i f if if 或 w h i l e while while 结构
if(x 3)
{printf(x is 3.\n);
}注意相等操作符 与赋值操作符 是两个不一样的运算符不要混淆。有时可能不小心写错但程序是不会报错的很容易出现意料之外的结果。 为了防止这种错误我们可以将变量写在等号的右边这样如果把 误写成 编译器就会报错
if(3 x )...
if(3 x)//报错同时需要注意多个运算符不宜连用
i j k;上面示例中连续使用俩个 是合法表达式程序不会报错。但往往会与你想要实现的结果大相径庭即不是保证变量 j j j 在 i i i 和 k k k 之间。因为关系运算符时从左往右算所以实际执行的是下面的表达式
i j k;i i i 和 j j j 的比较结果为真返回 1 为假返回 01 或者 0 与 k k k 比较 应该使用下面这种写法
i j j k;八、逻辑操作符 与运算符就是并且的意思两侧表达式都为真即为真否则为假 | | 或运算符就是或者的意思两侧至少有一个表达式为真则为真否则为假 逻辑取反操作符改变当表达式的真假 8.1、 与运算符 就是与运算符也是并且的意思。 是一个双目操作符使用方式是 a a a b b b 两边表达式都是真的时候整个表达式为真只要有一个为假则整个表达式为假。 int month 0;
scanf(%d, month);
if(month 3 month 5)
{printf(春季\n);
}这里表达式的意思是 m o n t h month month 既要大于等于3又要小于等于5必须同时满足。
8.2、 | 或运算符 | |就是或运算符也就是或者的意思。| |也是一个双目操作符使用方法是a || b | | 两边的表达式只要有一个是真整个表达式就是真两边都为假的时候才为假。 int month 0;
scanf(%d, month);
if(month 12 || month 1 || month 2)
{printf(冬季\n);
}九、条件操作符 条件操作符也叫三目操作符需要接受三个操作数形式如下 e x p 1 exp1 exp1 ? e x p 2 exp2 exp2 : e x p 3 exp3 exp3 条件操作符的计算逻辑是如果 e x p 1 exp1 exp1 为真 e x p 2 exp2 exp2 计算如果 e x p 1 exp1 exp1 为假 e x p 3 exp3 exp3 计算计算的结果是整个表达式的结果。 例使用条件表达式实现两个数中的较大值
#includestdio.hint main()
{int a 0;int b 0;scanf(%d %d, a, b);int m a b ? a : b;printf(%d\n, m);return 0;
}十、逗号表达式 e x p 1 e x p 2 e x p 3 … e x p N exp1exp2exp3…expN exp1exp2exp3…expN 逗号表达式就是用逗号隔开的多个表达式 逗号表达式从左到右一次执行整个表达式的结果是最后一个表达式的结果。 代码一
//c是多少
int main()
{int a 1;int b 2;int c (a b, a b 10, a, b a 1);return 0;
}上述逗号表达式 a b 结果为 0 但是不重要因为并没有对任意变量赋值不产生结果a b 10 将 a a a 赋值为 12a 不产生任何效果b a 1将 b b b 赋值为 13 逗号表达式的结果为最后一个表达式的结果 c c c 结果为13 代码二
int main()
{int a 0, b 0, c 0, d 0;if (a b 1; d c / 2, d 0){}return 0;
}前面两个表达式正常算但真正起到判断作用的还是d 0但是前面表达式的运算结果可能会影响最后一个表达式。 没想到吧 i f if if 语句还能这么写
代码三
a get_val();
count_val(a);while (a 0)
{//业务处理//……a get_val();count_val(a);
}这段代码的逻辑是先对 a a a 进行处理如果 a 0 a0 a0 进行业务处理处理完后再对 a a a 进行处理如此循环。 不难发现这段代码有点冗余怎么办呢 这时就可以巧用逗号表达式了 while (a get_val, count_val(a), a 0)
{//业务处理
}怎么样是不是很巧妙呢。 这里可能有小伙伴会说可以用 d o − w h i l e do-while do−while 循环但是 d o − w h i l e do-while do−while 循环是一上来直接进行循环并没有开始的判断部分。
十一、下标引用与函数调用操作符 下标引用操作符 [ ] 函数调用操作符 ( ) 怎么样没想到吧原来他两也是操作符
11.1、[ ] 下标引用操作符 操作数一个数组名 一个索引值
int arr[10];//创建数组
arr[9] 10;//实用下标引用操作符
//[ ]的两个操作数是 arr 和 911.2、( ) 函数调用操作符 接受一个或者多个操作数第一个操作数是函数名剩余的操作数就是传递给函数的参数。
int Add(int x, int y)
{return x y;
}int main()
{printf(hehe\n);//( )函数调用操作符int ret Add(2, 3);//( )函数调用操作符return 0;
}函数调用操作符至少一个操作数操作数无上限
十二、 结构成员操作符 12.1、结构体 C语言中已经提供了内置类型如char、short、int、long、float、double等但是仅仅只靠这些内置类型还是不够的。 假设我们想描述一个想学生描述一本书这时单一的内置类型肯定是不行的。描述一个学生需要名字、年龄、学号、身高、体重等描述一本书需要作者、出版社、定价等。 C语言为了解决这个问题增加了结构体这种自定义的数据类型让我们可以自己创造合适的类型 结构体是一些值的集合这些值称为成员变量。结构的每个成员可以是不同类型的变量如标量、数组、指针、甚至是其他结构体。 1结构体的声明
struct tag//结构体标签
{member-list;//成员列表
}variable-list;//结构体变量例如描述一个学生
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}//分号不能丢2结构体的定义和初始化
//变量的定义
struct Stu
{char name[15];int age;
}p1, p2, p3; //声明类型的同时定义多个变量struct Stu p4; //定义结构体变量
//这些定义的变量都是全局变量//初始化
struct Stu p5 { Zhangsan,20 };//指定顺序初始化
struct Stu p6 { .age 18,.name lisi };12.2、结构体成员访问操作符 1直接访问 结构体成员的直接访问都是通过点操作符 . . .访问的。点操作符接受两个操作数。
#includestdio.hstruct Point
{int x;int y;
}p { 10,20 };int main()
{printf(x: %d y: %d, p.x, p.y);return 0;
}使用方式结构体变量 . . . 成员名 2间接访问 有时我们得到的不是一个结构体变量而是得到了一个指向结构体的指针。如下所示
#includestdio.hstruct Point
{int x;int y;
};int main()
{struct Point p { 1,2 };struct Point* ptr p;ptr-x 10;ptr-y 20;printf(x %d y %d\n, ptr-x, ptr-y);return 0;
}使用方式结构体指针 - 成员名
十三、操作符的属性优先级、结合性 C语言中操作符有两个重要的属性优先级、结合性这两个属性决定了表达式求值的计算顺序。
13.1、优先级 优先级是指一个表达式中有多个操作符根据每个操作符的优先级大小判断哪个操作符先执行。 例如
3 4 * 5上述表达式中既有加法运算符又有乘法运算符。由于乘法运算符的优先级更高所以会先计算 4 * 5。
13.2、结合性 当两个操作符的优先级相同该怎么办呢这时就要用结合性来判断了。根据运算符是左结合还是右结合决定执行顺序。大部分运算符是左结合即从左到右执行当然也有少部分运算符是右结合即从右到左执行比如赋值运算符
5 * 6 / 2;上面例子中* 和 /d的优先级相同但它们都是左结合运算符所以从左到右执行先计算 5 * 6再计算 / 2。 表格来源cppreference.com
十四、表达式求值 14.1、整型提升 C语言中,整形算术运算总是至少以整形类型的精度来进行的。 为了获得这个精度表达式中的字符和短整型操作数在使用之前被转换为普通整型这种转换称为整型转换。 如何进行整型提升呢 有符号整数整型提升是按照变量的数据类型的符号位来提升。无符号整数提升高位补 0 。 表达式整形运算要在CPU的相应运算器件内执行CPU内整型运算器ALU的操作数的字节长度一般就是 i n t int int 的字节长度同时也是CPU的通用寄存器的长度。 因此即使两个 c h a r char char 类型的相加在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。 通用CPU是难以直接实现两个 8 比特字节直接相加运算虽然机器指令中可能有这种字节相加指令。所以表达式中各种长度可能小于 i n t int int 长度的整型值都必须整型转换为 i n t int int 或者 u n s i n g e d i n t unsinged int unsingedint ,然后才能送入CPU去执行运算。 下面我们看一段代码
#includestdio.hint main()
{char a 3;char b 127;char c a b;printf(%d\n, c);
}上述代码的结果是多少呢会是 130 吗别急我们一步步来看。 变量 a a a 中存的是整数 3 在内存中存的是32位二进制序列即00000000 00000000 00000000 00000011。而变量 a a a 是 c h a r char char 类型只能存放 1 个字节即00000011同理变量 b b b 中存放的是01111111在执行char c a b;语句时不是让他们直接相加而是先进行整形提升再相加。即 00000000 00000000 00000000 00000011 00000000 00000000 00000000 01111111 00000000 00000000 00000000 10000010因为变量 c c c 是 c h a r char char 类型只有一个字节所以 c c c 中存放的是10000010printf(%d\n, c);中我们知道%d 打印的是有符号整数所以在打印的时候也会发生整型提升由于 c h a r char char 类型在大部分编译器上相当于 u n s i g n e d unsigned unsigned c h a r char char 类型因此整型提升按符号位来提升即11111111 11111111 11111111 10000010。而上述整型提升所得到的是补码在内存中所有的存储和运算都是补码的形式只有打印时是按原码打印由补码得原码10000000 00000000 00000000 01111110 —— –126 运行结果 结果是 --126你们做对了吗。
14.2、算术转换 如果某个操作符的各个操作数属于不同的类型那么除非其中一个操作数转换为另一个操作数的类型否则操作就无法进行。 下面的层次体系称为寻常算术转换 long doubledoublefloatunsigned long intlong intunsigned intint 如果某个操作数的类型在上面这个列表中排名靠后那么首先要转化为另外一个操作数的类型后执行运算。 下面我们来看一道题
//求下面代码的输出结果#includestdio.h
int main()
{int i 0;i--;if (i sizeof(i)){printf(\n);}else{printf(\n);}return 0;
}运算结果 为什么呢 --1 还能比 4 大别急我们一起来看看 首先整型变量 i i i 初始化为 0 后自减得 --1在if (i sizeof(i))语句中 i i i 与 s i z e o f ( i ) sizeof(i) sizeof(i) 比较因为 s i z e o f sizeof sizeof 至少也是 u n s i g n e d i n t unsigned int unsignedint ,比 i n t int int 排名靠前 i i i 发生整型转换–1 的补码是11111111 11111111 11111111 11111111整型转换后成了一个很大的数 2 32 − 1 2^{32}-1 232−1这样一比较答案即是 。 好啦本期关于C语言操作符就介绍到这里啦希望本期博客能对你有所帮助同时如果有错误的地方请多多指正让我们在C语言的学习路上一起进步