【C语言】操作符

一、算术操作符 + - * / %

   1.除法/

        (1).整数除法

int a = 5 / 2;
printf("a = %d", a);

a = 2        //除出来的结果只取整数

        (2).小数除法

double a = 5.0 / 2;
double b = 5 / 2.0;
printf("a = %lf", a);
printf("b = %lf", a);

a = 2.500000

b = 2.500000        //除号两边至少有一个是浮点数

   2.取模%

int a = 5 % 2;
printf("a = %d", a);

a = 1        //两边操作数只能是整型

二、移位操作符

   1.右移操作符>>,移动的是二进制位

        (1).算术移位:先把整数转换成二进制数(计算时负数应该是补码形式,反码+1),整体向右移动,丢弃最后一位,前面补符号位

        (2).逻辑位移:先把整数转换成二进制数,整体向右移动,丢弃最后一位,前面补0

   2.左移操作符<<,整体向左移动,丢弃第一位(符号位不会丢弃),直接最后一位补0

三、位操作符,两边操作数都是整数

   1.按位与&:先把整数转换为二进制数(负数为补码形式),同为0为0,同为1为1,不同为0,真真才真

   2.按位或|,同为0为0,同为1为1,不同为1,假假才假

   3.按位异或^,相同为0,不同为1

四、赋值操作符 =

a = x = y + 2;
相当于 
x = y + 2;
a = x; 

五、复合赋值符 +=  -=  *=  /=  %=  >>=  <<=  &=  |=  ^=

a += 2;
相当于 
a = a + 2;

六、单目操作符(只有一个操作数)

   1. !  -  + 

   2. &          取地址 

   3. sizeof   计算所占内存空间大小

      sizeof a 计算变量可以去掉括号,sizeof(int)计算类型不能省略括号

      注意数组计算所占内存空间大小int arr[10];------>sizeof(int [10])或者sizeof(arr)

        例1

short a = 0;
int b = 2;
printf("%d\n", sizeof(a = b + 1));
printf("%d\n", a);

结果是2 0

第一个因为a是short型,short型占2个字节,不管赋值多少都是short型

第二个因为sizeof里的表达式不计算在真实计算中,所以a还是0

        例2

void test(int arr[])
{
    printf("%d\n", sizeof(arr));
}

int main()
{
    int arr[10] = {0};
    test(arr);
}

结果是4或8

因为数组作为参数传进去需要指针来接收,此时test函数里的arr就是指针,而指针所占内存空间大小在32位平台上是4个字节,64位平台上是8个字节,所以结果是4或8 

   4. ~        二进制按位取反

        注意电脑里存储的是补码,所以按位取反(符号位也取反)后需计算其原码

   5. -- ++     分为前置和后置

        前置:先++,再使用

        后置:先使用,再++

int a = 2;
printf("%d\n", ++a);    //结果为3
printf("%d\n", a++);    //结果为2
printf("%d\n", a);    //结果为3

   6. *           间接访问操作符(解引用操作符)

   7. (类型)   强制类型转换

七、关系操作符 >  >=  <  <=  !=  ==

八、逻辑操作符(只看真假)

   && 逻辑与        真真才真

        例1

int i = 0, a = 0, b = 1, c = 2, d = 3;
i = a++ && b++ && ++c;
printf("%d, %d, %d, %d", a, b, c, d);

结果为1, 1, 2, 3

首先a++是先使用再加,所以第一个逻辑与的左边为0,此时第一个逻辑与就已经得出计算结果为0,所以不用计算后面的b++,而后面也是逻辑与所以后面的++c也不用计算,所以电脑不会计算b++和++c,b还是1,c还是2

逻辑与左边结果为假时,右边不管真假也不会计算 

   || 逻辑或        假假才假

逻辑或左边结果为真时,右边就不会再计算

九、条件操作符

表达式1 ? 表达式2 : 表达式3

如果表达式1为真,计算表达式2,;否则计算表达式3

a > 5 ? b = 1 : b = 2;

或者

b = (a > 5 ? 1 : 2); 

十、逗号表达式 

用逗号隔开的多个表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

d = (a = a + 2, a > 0, b > a, c = a + b);

或者

if(a > 0, a++, b > a)

或者

while(a = fun1(), b = fun2(), b > 0)

十一、下标引用操作符 [ ] (有两个操作数)

a[4] = 2;        a和4就是操作数

十二、函数调用操作符( ) (一个或多个操作数)

函数名和多个参数就是操作数

十三、结构体成员访问操作符  . ->

//创建一个结构体类型
struct Stu
{
    char name[20];
    int age;
    char id[20];
}

//创建一个struct Stu类型的对象
//结构体的初始化用花括号
struct Stu s1 = {"张三", 20, "10001"};

//使用.访问结构体成员
//结构体变量.成员名
s1.name;
s1.age;
s1.id;

//使用->访问结构体成员
//先用一个指针变量存放s1的地址
struct Stu* ps = &s1; 
ps->name;
(*ps).name;

十三、隐式类型转换

1.整型提升

只要是char或短整型等位数比int小的,参与运算时都会整型提升

char a = 3;
char b = 127;
char c = a + b;

c输出为:-126

这是因为整型有32位,为了转换为字符型,只取后八位: 

 

 然后当两个char类型相加时(a+b时),需要整型提升,对于有符号的类型,如果第一位是0,补的24位数都是0,反之亦然:

 再将加后的结果赋给c,也是取后八位:

c只要参与表达式运算就会整型提升,所以将c整型提升,第一位是1,前面补1:

char c = 3;
sizeof(c);  //输出1
sizeof(+c);  //正c,输出4
sizeof(!c);  //输出1

只要c参与运算就会整型提升,但是为啥!c是1,没搞懂 

2. 算术转换

 位数大于或等于int类型的类型,会将位数小的类型转换为位数大的类型

比如int和float,要先将int转换为float类型再计算

c+--c; 

//这个表达式有歧义。就是说如果c为1,那么可以看作1+--c,然后--c得0,表达式得1。也可以看作c+--c,--c得0,那么c = 0,表达式就是0+0得0。所以并不能判断第一个c的值到底是多少

这个代码也有问题,不能判断先调用哪个fun()函数,虽然*优先级大于+

int i = 0;

int ret = (++i) + (++i) + (++i);

这个代码在不同的操作系统下会得出不同的答案,所以这个代码也是有问题的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值