c语言之变量总结(我的C语言日记09-操作符)

操作符算数操作符

% 取模操作符,左右操作数都必须为整数/ 除号等, - * 的左右操作数可以为浮点数或整数

移位操作符

右移操作符:1.算术右移右边丢弃,左边补原符号位

int main()//算术右移,右边丢弃,左边补原符号位 { int a = -1;//负数按照补码的方式存储,正数存储的也是补码(正数的补码和原码相同) //1000000000000001-原码 //1111111111111110-补码 //1111111111111111-补码 int b = a >> 1;//移位移的是内存中的二进制 printf("%d\n", b); return 0;//结果为-1,证明负数右移之后还是负数 }

c语言之变量总结(我的C语言日记09-操作符)(1)

​2.逻辑右移右边丢弃,左边补0

右移一位有除二的效果

int main() { int a = 16; int b = a >> 1; int c = a >> 2; printf("%d %d\n", b,c);//结果分别为8 4 return 0; }

c语言之变量总结(我的C语言日记09-操作符)(2)

​左移操作符:左边丢弃,右边补0有乘二的效果

int main() { int a = 5; int b = a << 1; printf("%d\n", b); return 0;//10 }

负数左移还是负数

​​

int main() { int a = -5; int b = a << 1; printf("%d\n", b); return 0;//-10 }

c语言之变量总结(我的C语言日记09-操作符)(3)

​警告⚠

1.不要移动负数位,是未定义的行为

int num = 10; num >> -1;///错误

2.只能作用于整数

&、|、^&按位与​

int main() { //&按2进制位与 int a = 3; int b = 5; int c = a&b; //011 //101 //001 printf("%d\n", c); return 0; }

|按位或​

int main() { //|按2进制位或 int a = 3; int b = 5; int c = a | b; //011 //101 //111 printf("%d\n", c);//7 return 0; }

^按位异或​

int main() { //^按2进制位异或 相同为0,相异为1 int a = 3; int b = 5; int c = a^b; //011 //101 //110 printf("%d\n", c); return 0; }

​练习:编辑代码实现求一个整数存储在内存中的二进制中的1的个数

int main() { int num = 0; int count = 0; scanf("%d", &num); //统计num的补码中有几个1 while (num) { if (num % 2 == 1)//判断末位是否为1 count ; num = num / 2;//去掉判断过的末位 } printf("%d\n", count); return 0;//但负数会出现问题 }

​但负数会出现问题

int main() { int num = 0; int count = 0; scanf("%d", &num);//当num&1,比如num=3即0011,num&1即为0011&0001,末位为1时&1必定为1,末位是0&1必定是0 int i = 0; for (i = 0; i < 32; i ) { if (1 == ((num >> i) & 1)) count ; } printf("%d\n", count); return 0; }

逻辑操作符

&&逻辑与 ||逻辑或逻辑与或和按位与或是有区别的,按位与或:二进制对应位进行与或逻辑与或:判断数字本身的真假​

int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a && b && d ;//a=0&&后面都为假,不运行//用后自加一 printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d); return 0;//1 2 3 4 }

&&

左边为假&&后面不计算​

int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a && b && d ;//a=0为假&&后面不计算,不运行//用后自加一 printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d); return 0;//1 2 3 4 }

左边为真时&&后计算​

int main() { int i = 0, a = 1, b = 2, c = 3, d = 4; i = a && b && d ; printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d); return 0;//2 3 3 5 }

​||

左边为真时||后不计算

int main() { int i = 0, a = 1, b = 2, c = 3, d = 4; i = a || b || d ;//a=1为真||后面的不计算,然后自加一 printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d); return 0;//2 2 3 4 }

条件操作符

格式为:表达式1?表达式2:表达式3;表达式1为真时结果为表达式2,表达式为假时结果为表达式3​

int main() { int a = 0; int b = 0; if (a > 5) b = 3; else b = -3; //用条件操作符来表示 b = (a > 5 ? 3 : -3); return 0; }

逗号表达式

从左向右依次执行,整个表达式的结果是最后一个表达式的结果​

int a=1;int b=2;int c=(a>b,a=b 10,a,b=a 1);c的值为13

还可以简化表达式

a = get_val();count_val(a);while (a > 0){//业务处理a = get_val();count_val(a);}//----逗号表达式优化---while (a = get_val(), count_val(a), a > 0){//业务处理}

下标引用、函数调用和结构成员[]下标引用操作符

操作数:一个数组名 一个索引值

int arr[10];//创建数组arr[9] = 10;//实用下标引用操作符[]的两个操作符是arr和9

函数调用操作符

调用函数的时候的()就是函数调用操作符,定义函数的()不是()的操作数有:函数名,参数

结构成员

struct Stu { char name[20];//成员变量 int age; char id[20]; }; int main() { int a = 10; //使用struct Stu这个类型创建了一个学生对象s1,并初始化 struct Stu s1 = {"张三",20,"2019010305"}; printf("%d\n", s1.age); //结构体变量.成员名//.操作符可以访问成员 printf("%s\n", s1.id); struct Stu* ps = &s1; printf("%d\n", (*ps).age); printf("%d\n", ps->age);//结构体指针->成员名 return 0; }

​struct Stu{}相当于图纸,根据图纸建造出来名为s1的房子,所以struct Stu s1占用内存空间,可以存放各种参数

表达式求值隐式类型转换

c的整型算数运算总是至少以缺省整型类型的精度来进行的为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

整型提升是按照变量的数据类型的符号位来提升的(高位补符号位)​

int main() { char a = 3; //00000000000000000000000000000011 正常一个整数所占32位 //00000011这就是char a //但char只能存放一个字节,要发生截断,取低位一个字节 char b = 127; //00000000000000000000000001111111 同理 //01111111这就是char b char c = a b;//计算时进行整型提升 //00000000000000000000000000000011 //整型提升:高位补符号位 //00000000000000000000000001111111 //整型提升:高位补符号位 //00000000000000000000000010000010 a b得到c,因为c是char类型要截断 //10000010就是char c printf("%d\n", c);//要打印整型//整型提升:高位补符号位 //11111111111111111111111110000010 - 补码//因为是负数,所以要求原码 //11111111111111111111111110000001 - 反码 //10000000000000000000000001111110 - 原码//-126 return 0; }

算术转换

类型不同的操作数进行运算,低精度的类型转换为高精度的类型,类型一致再进行运算

自加和自减详解

总结:自增减( /--)前置:在运算之改变变量自增减( /--)后置:在运算之改变变量

1.​

int main() { int i = 0; int j = i i;// i优先级高于i ,所以相当于int j= i i ; //此时i=0,1(此时i=1) 1(此时i=2)=2 int k = --i i--;//此时i=2,(此时i=1)1 1(此时i=0)=2 printf("%d %d %d\n", i, j, k); return 0; }

​当运行int j = i i;分析优先级:自加高于 ,两个自加同级从左向右计算;其中 i的优先级比i 高,即变为int j= i i 运算之前:因为 i,在运算之前使得变量i加一(0 1=1);此时i=1运算之中:加上i ,因为是后置 ,所以此时i仍然是1,所以为1 1=2赋值给j运算之后:因为i ,在运算之后使得变量i加一(1 1=2);此时i=2当运行int k = --i i--;运算之前:因为--i,在运算之前使得变量i减一(2-1=1);此时i=1运算之中:加上i--,因为是后置--,所以此时i仍然是1,所以为1 1=2赋值给j运算之后:因为i--,在运算之后使得变量i减一(1-1=0);此时i=0

2.

int main() { int i = 0; int j = i i ;//0 0(i=1)=0 printf("%d %d\n", i, j); return 0; }

运行int j = i i ;运算之前:无运算之中:加上i ,因为是后置 ,所以此时i仍然是0,所以为0 0=0赋值给j运算之后:因为i ,在运算之后使得变量i加一(0 1=1);此时i=1

3.​

int main() { int i = 0; int j = i i;//1 1=2 printf("%d %d\n", i, j); return 0; }

​运行 int j = i i;分析优先级:自加高于 ,即变为int j= i i;运算之前:因为 i,在运算之前使得变量i加一(0 1=1);此时i=1运算之中:加上i,此时i仍然是1,所以为1 1=2赋值给j运算之后:无

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页