首页 > 其他分享 >【C语言有这个就够了】四.操作符详解(2)

【C语言有这个就够了】四.操作符详解(2)

时间:2022-10-11 20:00:12浏览次数:48  
标签:操作数 return int 就够 C语言 char ++ 操作符 printf

(七)关系操作符

​<  <=  >  >=  !=  ==​

都挺简单,唯一注意=和==

(八)逻辑操作符

逻辑与  &&

逻辑或  ||

#include<stdio.h>
int main()
{
int a = 9;
int b = 1;
int c = 0;
printf("%d\n", a & b);
printf("%d\n", a | b);//更多的是计算

printf("%d\n", a && b);
printf("%d\n", a || b);//更多的是逻辑判断
return 0;
}

在c语言中,非0为真,0为假;

笔试题分析:

#include <stdio.h>
int main()
{
int i = 0,a=0,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;
}

【C语言有这个就够了】四.操作符详解(2)_操作符

&&的特点是只要前面运算为假了,后面的运算全部不进行。(因为都为假)

所以当计算到a++时,先使用a=0为假,后面运算停止,而a++使a自增1。

同理,当||遇到真时,后面的运算取消:

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

【C语言有这个就够了】四.操作符详解(2)_整型_02

(九)条件操作符---三目操作符

​exp1?exp2:exp3​

含义:

若1结果为真,计算表达式2,其结果为整个表达式的结果

若1结果为假,计算表达式3,其结果为整个表达式的结果

练习:

#include<stdio.h>
int main()
{
int a = 20;
int b = 10;
b = (a > b ? a : b);
printf("%d", b);
return 0;
}

(十)逗号表达式

​exp1,exp2,exp3........expn​​​

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

1.

int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);

a=12;b=13;c=13

2.

if (a =b + 1, c=a / 2, d > 0)

取决于d>0;

(十一)下标引用,函数调用和结构成员

1.【】下标引用操作符

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

int arr[10];
arr[9]=10;

2.()函数调用操作符

接受一个或多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

int max=get_max(a,b)   //3个操作数

3.访问一个结构的成员

​结构体.成员名​

​结构体指针->成员名​

#include<stdio.h>
struct Stu //创建了一个结构体类型————struct Stu
{
char name[20];
int age;
char id[20];
};

int main()
{
int a = 10;
struct Stu s1 = { "小明",20,"10293845648" }; //使用struct Stu创建了一个学生对象s1
struct Stu* ps = &s1;

printf("%s\n", ps->name);
printf("%d\n", ps->age);

//printf("%s\n", (*ps).name);
//printf("%d\n", (*ps).age);

//printf("%s\n", s1.name);
//printf("%d\n", s1.age);
//printf("%s\n", s1.id);
return 0;
}

(十二)表达式求值

求值顺序由操作符的优先级和结合性决定;

1.隐式类型转换

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

1.1例如:
#include<stdio.h>
int main()
{
char a=3;
char b = 127;
char c = a + b;
printf("%d", c);
return 0;
}

结果是130吗?

我们发现计算机输出了-126这个值,分析在程序中体现:

【C语言有这个就够了】四.操作符详解(2)_操作符_03

#include<stdio.h>
int main()
{
char a=3;
a的2进制转换为
//00000000000000000000000000000011
//a只能放一个字节,规则是放00000011————a
char b = 127;
//00000000000000000000000001111111
//b只能放一个字节,规则是放01111111————b
char c = a + b;
//a+b
//00000011
//01111111
//整形提升是按照变量的数据类型的符号位来提升的,高位补充符号位,无符号数补充0.
//000000000000000000000000000000011
//000000000000000000000000001111111
//000000000000000000000000010000010
//10000010————c
//111111111111111111111111110000010————c的补码
//111111111111111111111111110000001————反码
//100000000000000000000000001111110————原码
//-126
printf("%d", c);
return 0;
}
​1.2负数的整形提升:

char c1 = -1;

变量c1的二进制位(补码)中只有8个比特位: 1111111

整形提升的时候,高位补充符号位,即为1

提升之后的结果是: 11111111111111111111111111111111

1.3正数的整形提升

char c2 = 1;

变量c2的二进制位(补码)中只有8个比特位: 00000001

整形提升的时候,高位补充符号位,即为0

提升之后的结果是: 00000000000000000000000000000001

1.4无符号整形提升,高位补0
1.5意义

​表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 ,一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

典例1

int main()
{
char a = 0xb6;
short b = 0xb600;
//10110110
int c = 0xb6000000;
if (a == 0xb6)
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c");
return 0;
}

【C语言有这个就够了】四.操作符详解(2)_操作数_04

a,b整形提升之后,变成了负数

典例2

#include<stdio.h>
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(!c));
return 0;
}

【C语言有这个就够了】四.操作符详解(2)_整型_05

char原本是一个字节,但只要c发生表达式运算,就会发生整型提升。

2.算术运算

long double
double
float
unsigned long int
long int
int

​如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类 型,否则操作就无法进行

​如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运 算。这就是寻常算术转换。

但是算术转换要合理,不然会产生错误;

3.操作符的属性

1.优先级(相邻操作符运算优先级高的)

2.结合性(在优先级相同的情况下考虑结合性)

3.是否控制求值顺序

3.1问题表达式

​a*b+c*d+e*f​

计算顺序可能有:

a*b 
c*d
a*b + c*d
e*f
a*b + c*d + e*f

a*b 
c*d
e*f
a*b + c*d
a*b + c*d + e*f



​c+ --c​

不能确定+操作符的左操作数的获取在右操作数计算之前还是之后。



int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}

非法表达式,在不同编译器的结果不同。



int fun()
{
    static int count = 1; //static让1没被销毁
    return ++count; } //2,3,4三种
int main()
{
    int answer;
    answer = fun() - fun() * fun();
    printf( "%d\n", answer);//输出多少?
    return 0; }

3个fun()的调用顺序不确定,结果不同



#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0; }

在不同编译器下结果不同;


总结:要有唯一计算路径











标签:操作数,return,int,就够,C语言,char,++,操作符,printf
From: https://blog.51cto.com/u_15796276/5747888

相关文章

  • C语言编译过程
    前言很多人做了很久的C/C++,也使用了很多的IDE,但很多人却不明白他们所写的.C文件在计算机底层怎么生成机器能够识别的二进制文件,这种变化经历了什么过程,这边文章将会对C语......
  • 初始C语言和程序设计
    这是我写的第一篇文章关于讲解C语言程序设计的,希望通过此,让大家都能初步了解C语言,也希望自己通过写这篇文章对C语言有重新的的认识,如果有不好不对的地方,麻烦大家提出,谢谢。......
  • C语言之函数
    结构化程序设计主张按功能来分析需求,主要原则自顶向下,逐步求精,模块化等。主张按功能把软件系统逐步细分,每个功能都负责对数据进行一次处理,每个功能接收一些数据,处理完后......
  • C语言每日一题——第十四天
    第十四天这一次小明想要尝试一下语言分析……当然是最简单的文本匹配。首先“玩家”会输入长度为10的一串文字,内容全部由大小写字母、数字、空格组成,小明计划用程序匹配......
  • 【C语言_21】处理字符串的函数!
    前言使用以下函数均需要添加头文件#include<string.h>1.strlen函数获取字符串的长度从第一个字符开始直到遇见\0,返回字符串的长度size_tstrlen(constchar*str);//size_t......
  • 首篇博客:C语言初体验
    这是我的第一篇博客,我打算以周记的形式来写我的博客文章,我是22届郑州轻工业大学计算机类大一学生,刚刚接触c语言想要写一下自己的感受。在起初学c语言时感觉并非太难,而在实......
  • 小C语言--词法分析程序
    小C语言文法 1.<程序>→<main关键字>(){<声明序列><语句序列>}2.<声明序列>→<声明序列><声明语句>|<声明语句>|<空>3.<声明语句>→<标识符表>;4.<标识符表>→<标识符>......
  • C语言找画笔(全网最详)
    题目:豆豆对数字的执着,让他在理科领域游刃有余,但他近乎疯狂的投入也使父母有些担心,为了让孩子能够全面发展,决定拓宽他的学习领域。正好家旁边有个绘画培训中心,父母就给豆豆报......
  • 【C语言_20】const与#define的用法及区别
    1.const关键词的用法const在实际编程中用得并不多,const是constant的缩写,意思是“恒定不变的”!它是定义只读(不能修改)变量的关键字,或者说const是定义常变量的关键字。......
  • 221010嵌入式系统高级C语言编程_笔记
    C语言不检查数组越界和内存缓冲区越界编译器对局部变量有两种存储方式,对于简单数据类型的变量(比如int,char,short或者指针变量等)编译器会首先尽可能的采用CPU内部的通用寄存......