一.单目操作符的补充

(1. ~  表示对一个二进制数按位取反,如 1010 按位取反之后则变成 0101 

#include<stdio.h>
int main(void)
{
int a = 0;  //int为整型,占用4字节,则表示0000····0(32个0)
int b = ~a; //按位取反 a 得到的结果则为 1111····1(32个1)
return 0
}

最终输出结果为-1 ,涉及到原码、反码、补码的概念,负数在内存中存储的时候,储存的是二进制的补码,这里的变量b为有符号的整型,在补码中最高位如果为有符号数则表示符数,若为0则表示正数,二printf()函数打印出来的则是这个数的原码,以下是原码、反码、补码的一个关系

原码,反码,补码的关系

原码--->反码:符号位(最高位)保持不变,其余位按位取反

反码--->补码:反码+1

补码--->反码:补码-1

反码--->原码:符号位(最高位)保持不变,其他位按位取反

我们举上面的例子:

int a=0

int b=~a

printf("b=%d\n",b);

由于a为整型占4个字节,32bit,那么换算成二进制则为:00000000000000000000000000000000

将a按位取反的值赋给变量b,则b的二进制值为:11111111111111111111111111111111

这时我们得到的是补码,而printf()输出的为原码,所以我们需要进行转换,先将补码转换为反码得到:

11111111111111111111111111111110  ,随后将反码转换为原码,遵循规则最高位不变,则得到:

10000000000000000000000000000001  ,此时注意最高位是表示符号的,因为1为有符号数,所以二进制值为负,则变成-0000000000000000000000000000001,化简得-1,以下是程序运行的截图:

C语言第三节课--课程总结(1)_补码


(2.  -- 与 ++  操作符,其中还分为前置++与后置++,前置--与后置-- ,来看以下代码

#include<stdio.h>
int main(void)
{
int a = 10;
int b = a++;
printf("a=%d b=%d\n",a,b);
getchar();
return 0;
}

这里程序运行的结果为a=11 b=10 ,原因是 第五行代码中先将a的值赋给b,这时候a=10 b=10,之后a再进行自增,此时a=11 b=10,也就是先使用,后++,这就是后置++的实际运用

下面来看前置++

#include<stdio.h>
int main(void)
{
int a = 10;
int b = ++a;
printf("a=%d b=%d\n",a,b);
getchar();
return 0;
}

这次程序的运行结果为a=11 b=11,原因是第五行代码是先将a进行++操作,使得a=11 随后赋值给b,此时a=11 b=11

说完++,接下来说一下后置 --,其实与++同理

#include<stdio.h>
int main(void)
{
int a = 10;
int b = ++a;
printf("a=%d b=%d\n",a,b);
getchar();
return 0;
}

这里和后置++一样,先将a = 10 赋值给 b,此时 a=10 b=10,随后a进行自减,a=9 b则保持不变,所以最终输出结果为a=9 b=10

同理前置 -- 一样

#include<stdio.h>
int main(void)
{
int a = 10;
int b = --a;
printf("a=%d b=%d\n",a,b);
getchar();
return 0;
}

a先进行自减使得a=9,随后将a的值赋给b,b=9,此时a=9 b=9


(3.强制类型转换,如以下代码

#include<stdio.h>
int main(void)
{
int a = 3.14;
return 0;
}

编译器在编译这段代码时会抛出警告大意是正在将一个double(浮点)类型的数据转换为int(整型)的数据类型,可能会丢失数据,其中丢失的数据为小数点后的 .14 而强制类型转换可以避免编译过程中产生警告,如下代码:

#include<stdio.h>
int main(void)
{
int a = (int)3.14;  
getchar();
return 0;
}

在数值的前面加上一个括号,并在括号内说明需要强制类型转换的目标数据类型,如这里是强制将3.14这个浮点数转换为int类型,注意!这样做虽然可以避免编译时出现告警,但极有可能会丢失数据,不建议使用此功能,如图:

C语言第三节课--课程总结(1)_操作符_02



二.关系运算符

关系操作符分为以下几类:

> 大于

< 小于

=> 大于等于

<= 小于等于

!=  不等于

==  等于


三.逻辑操作符 &&  与   ||

&&称为逻辑与也称为并且

||称为逻辑或也称为或者

补充:在C语言中非零为真,0为假

#include<stdio.h>
int main(void)
{
int a = 1;
int b = 2;
int c = a&&b;
printf("c=%d\n",c);
return 0;
}

这里输出的结果为1,因为a=1>0 b=2>0 两个数字大于0,为真,所以a&&b的值为1

#include<stdio.h>
int main(void)
{
int a = 0;
int b = 2;
int c = a&&b;
printf("c=%d\n",c);
return 0;
}

这里输出的结果则为0,即使b=2>0为真,但是a=0为假,&&是逻辑与操作符,需要两个都为真结果才能为真,否则就为假,所以这里输出的结果是0

说完逻辑与接下来说一下逻辑或 ||

#include<stdio.h>
int main(void)
{
int a = 0;
int b = 2;
int c = a||b;
printf("c=%d\n",c);
return 0;
}

这里程序的输出为1,可能有的人感到奇怪,明明a为0,是假呀,怎么结果会为1呢?其实逻辑或只要其中有一个值为真,那输出的结果就为真,只有当全为假的时候才会输出0,如图所示:

C语言第三节课--课程总结(1)_原码_03



四.条件操作符

exp1 ? exp2 : exp3

exp1代表着第一个表达式 ? 表示如果为真就执行表达式exp2,表达式exp2就是最终的结果,: 表示如果表达式为假则执行表达式exp3的语句,表达式exp3为最终结果,所以为三目操作符,如以下代码:

#include<stdio.h>
int main(void)
{
int a=10;
int b=30;
int c=(a>b ? a : b);
printf("c=%d\n",c);
getchar();
return 0;
}

程序最终输出的结果为30,原因是a=10 b=30 a>b这个结论显然不成立,所以为假,当表达式为假时

则会执行冒号后面的内容,获取b的值并将其赋值给c,所以最终输出的结果为30


五.逗号表达式(操作符)

exp1,exp2,exp3 ····· expN

其余的后续将介绍


六.下标引用、函数调用、结构成员

[]  下标

()  函数调用

.

->


1.下标引用操作符实例:

#include<stdio.h>
int main(void)
{
int arr[10] = {0};  //创建一个数组大小为10的数组
arr[5];             //访问下标为5的数组
return 0;
}

2.函数调用操作符实例:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int sum(int x,int y)
{
int z = x + y;
return z;
}
int main(void)
{
int number_1 = 100 , number_2 = 420;
int total = sum(number_1,number_2);  //函数调用操作符
printf("%d\n",total);
getchar();
return 0;
}

.  ->结构体操作符后续会补充进去

                                                                                                    2023/7/24

                                                                                                     王起舟