重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
算术操作符:+ - * / %
“%”操作符的两侧数字必须为整数,其余操作符的两侧数字既可以是整数,也可以是浮点数。“/”两侧的数字都为整数时,执行整数除法,否则执行浮点数除法。
int main()
{int a = 3 / 5; //整数除法
float b = 3.0 / 5; //浮点数除法
float c = 3.0 / 5.0; //浮点数除法
printf("%d %f %f", a, b, c);
return 0;
}
3. 移位操作符①<< :左移操作符,二进制序列左移一位,左边丢弃,右边补0;
②>>:右移操作符分为算术右移和逻辑右移。算术右移:二进制序列右移一位,右边丢弃,左边补原符号位;逻辑右移:二进制序列右移一位,右边丢弃,左边补0。
int main()
{int a = 5; //...00000101
int b = a<< 1; //...00001010
printf("%d\n", b);
int c = -1; //...11111111
int d = c >>1; //算术右移:补1,...11111111 逻辑右移:补0,0...11111111
printf("逻辑右移:%d\n", d);
return 0;
}
警告:对于移位操作符不能移动负数位,这个标准是未定义的。(a<<-1)
4. 位操作符&:按位与,将二进制序列按位进行与操作得到新序列(包括符号位)
|:按位或,将二进制序列按位进行或操作得到新序列(包括符号位)
^:按位异或(相同为0,不同为1),将二进制序列按位进行异或操作得到新序列(包括符号位)
int main()
{int a = 1;
int b = 5;
printf("%d\n", a&b); //输出:1
printf("%d\n", a|b); //输出:5
printf("%d\n", a^b); //输出:4
int c = -1;
int d = 5;
printf("%d\n", c&d); //输出:5
printf("%d\n", c | d); //输出:-1
printf("%d\n", c^d); //输出:-6
return 0;
}
如何不创建临时变量,来交换两个数的值?(通过异或操作符实现)
int main()
{int a = 5;
int b = 3;
printf("%d %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d\n", a, b);
}
求一个整数存储在内存中的二进制的1的个数。
int main()
{int a = 13;
int b = 1;
int count = 0;
for(int i=0;i<32;i++)
{count += a & b;
a = a >>1;
}
printf("%d\n", count);
return 0;
}
将二进制数5的第四位置1。
int main()
{int a = 5;
int b = 1;
a = a | (b<< 4 - 1);
printf("%d\n", a);
return 0;
}
将二进制数5的第三位置0。
int main()
{int a = 13;
int b = 1;
a = a ^ (b<< 3 - 1);
printf("%d\n", a);
return 0;
}
5. 赋值操作符6. 单目运算符=:
复合赋值运算符:
①+=:
②-+:
③*=:
④/=:
⑤>>=:
⑥<<=:
⑦&=:
⑧|=:
⑨^= :
6.1 sizeof!:逻辑反操作
-:负值
+:正值
&:取地址
sizeof:操作数的类型长度
~:对一个二进制数按位取反(包括符号位)
++:前置、后置++
–:前置、后置–
*:间接访问操作符(解引用操作符)
(类型):强制类型转换
int main()
{int a = 0;
int arr[10] = {0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(int [10]));
short s = 5;
int b = 10;
printf("%d\n", sizeof(s = b + 2)); //输出为2,sizeof括号内放的表达式不参与运算
printf("%d\n", s); //输出为5
}
6.2 sizeof和数组void test1(int arr[])
{printf("%d \n", sizeof(arr)); //输出为4或者8
}
void test2(char ch[])
{printf("%d \n", sizeof(ch)); //输出为4或者8
}
int main()
{int arr[10] = {0 };
char ch[10] = {0 };
printf("%d \n", sizeof(arr)); //输出为40
printf("%d \n", sizeof(ch)); //输出为10
test1(arr);
test2(ch);
return 0;
}
为什么调用函数内部的输出为4或者8呢?因为当数组作为参数调用函数时,实际上传输过去的值为数组首元素的地址。所以在函数内部,实际上是创建了一个指针用来接收传递过来的地址,因此此处的输出为4或者8。(32位系统输出4,64位输出8)
7. 关系操作符8. 逻辑操作符①>:
②>=:
③<:
④<=:
⑤!=:
⑥==:
逻辑与:&&
逻辑或:||
360面试题
int main()
{int i = 0, a = 0, b = 2, c = 3, d = 4; //将a换成1再计算一遍
i = a++ && ++b && d++;
//a=0时,输出为 1,2,3,4 (当a=0时,0与任何数相与都为0,因此系统不会再计算后面的表达式了)
//a=1时,输出为 2,3,3,5
//i = a++ || ++b || d++;
//a=1时,输出为 2,2,3,4 (当a=1时,1与任何数进行逻辑或运算都为1,因此系统不会再计算后面的表达式了)
//a=0时,输出为 1,3,3,4
printf("%d %d %d %d \n", a, b, c, d);
return 0;
}
9. 条件操作符b = (a >b ? 1 : 2);
//a>b为真,则b=1
//a>b为假,则b=2
10. 逗号表达式逗号表达式:从左向右依次计算,但是整个表达式的结果是最后一个表达式的值
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1); //逗号表达式,c为13
if (a =b + 1, c=a / 2, d >0) //最后一个表达式是if语句的条件
a = get_val();
count_val(a);
while (a >0)
{a = get_val();
count_val(a);
}
//如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{;
}
11. 下标引用、函数调用和结构成员
11.1 下标引用操作符int arr[10]; //创建数组
arr[9] = 10; //使用下标引用操作符。
//[ ]的两个操作数是arr和9。
11.2 函数调用操作符int add(int x, int y)
{return x + y;
}
int main()
{int a = 3;
int b = 4;
int c = add(a, b); //使用()作为函数调用操作符,add、a、b都是()的操作数。
printf("%d\n",c );
return 0;
}
11.3 访问一个结构体成员详情浏览链接第2部分
12 表达式求值表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
12.1 隐式类型转换C的整型算术运算总是以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
所以是如何进行整型提升的呢?①负数的整型提升:高位补1;②正数的整型提升,高位补0;③无符号整型提升,高位补0。
int main()
{char a = 3;
//00000011
//整形提升:0000000 00000000 00000000 000000011
char b = 127;
//01111111
//整形提升:00000000 00000000 00000000 01111111
char c = a + b;
//相加:00000000 00000000 00000000 10000010
//截断存入c中,c:10000010
printf("%d\n", c); //-126
//由于输出的类型为整型,所以对c进行整型提升
//整形提升:11111111 11111111 11111111 10000010(补码)
//反码:11111111 11111111 11111111 10000001
//原码:10000000 00000000 00000000 01111110
return 0;
}
实例1:
int main()
{char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a==0xb6) //将a整型提升后a变为负值
printf("a");
if(b==0xb600) //将b整型提升后a变为负值
printf("b");
if(c==0xb6000000) //c不需要进行整型提升,输出结果为c
printf("c");
return 0;
}
实例2:
int main()
{char c = 1;
printf("%u\n", sizeof(c)); //输出为1
printf("%u\n", sizeof(+c)); //输出为4,c需要进行表达式运算,所以此处进行了整型提升
printf("%u\n", sizeof(-c)); //输出为4,c需要进行表达式运算,所以此处进行了整型提升
return 0;
}
12.2 算术转换当表达式的操作符各个类型不同的话,则需要先将它们转化为同一类型的值再进行计算。
12.3 操作符的属性由低向高转换
long double
double
float
unsigned long int
long int
unsigned int
int
复杂表达式的求值有三个影响的因素。
1.一个表达式有值属性和类型属性两个属性。
该笔记是学习了B站up主:鹏哥C语言 的课程所写。课程传送门
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧