.算数操作符

发布时间:2026/7/1 2:28:52
.算数操作符 移位操作符使用条件只能对于 int类型 使用无符号整型这里算作正数。移位操作符移动的位数不能为负数标准未定义这种写法所以在不同编译器中有不同结果a. 左移 对整数的补码左移一位 左边丢弃右边补零b. 右移 对整数的补码右移一位 算数移位右边丢弃左边补原符号位逻辑移位右边丢弃左边补零 //算数移位和逻辑移位取决于编译器大部分是算数移位整数的二进制表达有三种原码,反码,补码对于正整数来说三种表达方式在数值上是相同的而负整数的三种表达在数值上并不相同//例 7 00000000 00000000 00000000 00000111——32位原码 00000000 00000000 00000000 00000111——32位反码 00000000 00000000 00000000 00000111——32位补码 // 由于 int 类型内存大小为 4 个字节其存储方式为32bit的二进制第一位为字符位为 1 表示负数0 为正数 -7 10000000 00000000 00000000 00000111——32位原码 11111111 11111111 11111111 11111000——32位反码 //反码是将原码中除字符位以外的bit位由 1 变为 0 由 0 变为 1 11111111 11111111 11111111 11111001——32位补码 //补码就是在反码的基础上 1 那么移位操作符是如何使用的下面我举一个例子int main() { int a 7; int b 0; b a 1; //此时输出 b 的结果为 14 —————— 00000000 00000000 00000000 00001110由于7的32位原码为 ——00000000 00000000 00000000 000000111。而正整数的原码补码相同我们遵循左移规则对a的补码左移一位左边的二进制数丢弃最右边补零得到补码 ——00000000 00000000 00000000 00001110。由于第一位的符号位为零其是正整数原码补码相同所以转换成十进制就是14。我们再举一个负数的例子int main() { int c -7; b c 1; //此时输出 b 的结果为 -14 ————— 11111111 11111111 11111111 11110010补码 }-7的原码反码补码上面已经列出这里不再写了我们根据左移规则对c的补码左移左边丢弃右边补零得到补码——11111111 11111111 11111111 11110010这里我们看到符号位为1得到的是一个负数我们先求反码对补码减去1得到反码11111111 11111111 11111111 11110001再求原码对反码除符号位的每一位进行0和1的互换得到原码10000000 00000000 00000000 00001110转换成十进制为-14同理对于右移操作符也是一样的方法算出补码按照规则右移在将结果的补码转换成原码变为十进制就能得到数值一定要记得在原码反码的转换中首位符号位是不变的但在移位的过程中符号位是可能改变的这也是为什么使用移位操作符会改变数值的正负。3.位操作符使用条件计算时两边的操作数要为 int类型a. 按位与 //与对于两个二进制数的两边都为1与的结果为1两边只要有0结果为0b.| 按位或 //或对于两个二进制数|的两边都为0或的结果为0两边只要有1结果为1c.^ 按位异或 //异或:对于两个二进制数相同结果为0相异结果为1按位的含义就是对于两个操作数按补码的二进制位每位单独进行比较我举一个例子//例1 int main() { int a 8; //00000000 00000000 00000000 00001000 8的补码 int b -4; //11111111 11111111 11111111 11111100 -4的补码 int c 0; c a b //00000000 00000000 00000000 00001000 结果的补码由于是正数所以原码也是这个结果为8 a | b //11111111 11111111 11111111 11111100 结果的补码 //11111111 11111111 11111111 11111011 反码 //10000000 00000000 00000000 00000100 原码结果为-4 a ^ b //11111111 11111111 11111111 11110100 补码 //11111111 11111111 11111111 11110011 反码 //10000000 00000000 00000000 00001100 原码结果为-12 }举一个用法//例2 int main() { int a 10; int b 20; a a ^ b;//10^20 b a ^ b;//10^20^20 //不建立新变量交换两个数值只适用于int类型 a a ^ b;//10^20^10 (20^200) }4.赋值操作符a. 赋值赋值操作符可以连续使用//例: int main() { int a 10; int b 20; int c 30; a b c 10;//输出的结果为a40b40 }b.复合赋值操作符 - * / % ^ | 复合赋值操作符本质上就是对被赋值的变量进行一次计算再将计算结果赋值给被计算变量自身//例 int main() { int a 0; a a 1; a 1; //这两种写法结果是相同的其他的复合赋值操作符同理 }5.单目操作符(只有一个操作数)a. 逻辑反操作//把真转为假把假转为真C语言中一般把0视为假非零视为真 b.- 负号 c. 正号e. 取地址(获取被操作实体的内存起始地址)当取地址数组名时结果为指向整个数组的指针代表整个数组的内存的起始地址即使和数组的首元素地址相同但在参与指针运算时的步长不同f.sizeof(操作数) 计算操作数的字节长度(类型变量数组等) //sizeof后的括号在某些情况下是可以省略的sizeof 运算符的结果是 size_t 类型它是重命名的unsigned __int64(无符号的8byte的int)sizeof 的操作数可以是下列项之一类型名称。若要将 sizeof 用于类型名称则该名称必须用括号括起。一个表达式。与表达式一起使用时可以使用或不使用括号指定 sizeof。 不计算表达式。当 sizeof 运算符应用到数组名时它将产生该数组的字节总数而非由数组名表示的指针的大小。 若要获取由数组名表示的指针的大小请将它作为参数传递给使用 sizeof 的函数。 例如#define _CRT_SECURE_NO_WARNINGS #includestdio.h int my_sizeof(int*arr) { return sizeof(arr); } int main() { int a 0; int arr[10] { 0 }; a my_sizeof(arr); printf(%d, a); }//输出的结果在64位环境为832位为4