首页 > 其他分享 >C 语言 【操作符(下)】

C 语言 【操作符(下)】

时间:2024-10-19 20:47:42浏览次数:6  
标签:操作数 语言 int 操作符 整型 sizeof 表达式

        说到这操作符下篇,各位看官老爷可得认真听听喽。主要就是说说这整型提升算术转换,对于初学者来说可能学到的内容太过浅显,今天就让我呀来带您好好唠唠。

        先接着上篇的内容给大家聊聊吧。

4、单目操作符(  ! -   +  &  sizeof  ~  --  ++  * )

        !   :   逻辑反操作

        -   :   负值

        +  :   正值

        &  :  取地址

        sizeof   :   操作数的类型长度

        ~  : 对一个数的二进制按位取反

        --  : 前置、后置--

        ++ :前置、后置++

        *   : 解引用操作符

        对于上面的这些操作符,在这里要提醒大家要注意的就是sizeof,它的返回值类型为unsigned int 类型,也就是无符号整型。还有要注意前置加加和减减(先加减再用),后置加加和减减(先用再加减)。

5、关系操作符 (>   >=   <   <=   !=    ==)

        这里要注意的是,在判断两数相等的时候要使用的是==操作符。在编程的过程中要注意在判断时错写成=。

6、逻辑操作符( &&   ||)

        &&    :  逻辑与

        ||       :  逻辑或

        这里来看一道例题:

#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\nd = %d\n", a, b, c, d);
    return 0;
}
//程序输出的结果是什么?

       这里有一点需要说明:在逻辑与的时候,当第一个操作数的值为0时,程序不会往下计算第二个操作数的值,因为一旦有0,逻辑与的结果就是0。所以在遇到的第一个操作数为0时,i的值就会被赋为0,且++b和d++不会被执行。相同的道理,在逻辑或的时候,当第一个操作数为1时,程序便不会计算后面的操作数,直接返回1。

7、条件操作符 (  exp1  ?  exp2  :   exp3  )

       exp1  ?  exp2  :   exp3  ,当表达式1的结果为真时,返回表达式2,否则返回表达式3。条件表达式可以用来简化代码。

if (a > 5)
        b = 3;
else
        b = -3;

        上面的程序可以简化为:

(a>5) ? b=3:b=-3 

 8、逗号表达式 (exp1, exp2, exp3, …expN )

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

int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式c是多少?

9、表达式求值

        9.1隐式类型转换

        终于说到这里了,这部分是操作符部分的难点,同样也是初学者最容易摸不着头脑的地方。废话不多说,现在开讲!

        C语言的整型算数运算总是至少以缺少整型类型的精度来进行的。说人话就是:像char  short类型的变量在参与运算的过程中会先将数据的长度增长为整型的长度,即需要增长成4个字节。为了获得整型的精度,表达式中的字符和短整型操作数在使用之前会被自动转换成普通整形,这种转换称为整型提升。

        整型提升的意义:

        表达式的整型运算要在CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的字节长度一般就是int 的字节长度,同时也是 CPU的通用寄存器的长度。 因此,即使两个 char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长度。 通用 CPU ( general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于 int 长度的整型值,都必须先转 换为 int 或 unsigned int ,然后才能送入 CPU 去执行运算。
//实例1
char a,b,c;
...
a = b + c;

        b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。

        如何进行整体提升呢?(整型提升是按照变量的数据类型的符号位来提升的)

//负数的整形提升
char c1 = -1;

        变量c1的二进制位(补码)中只有8个比特位:即 1111 1111 ,因为char是 singed char(有符号),所以再提升的时候,高位补充符号位1,所以提升的结果为0xFFFF(32个1)。

//正数的整型提升
char c2 = 1;

        变量c2的二进制位(补码)中只有8个比特位:即 0000 0001 ,因为char是 singed char(有符号),所以再提升的时候,高位补充符号位0,所以提升的结果为:0x0001。

        讲完了这些,我们可以来看一个例子:

#include <stdio.h>
//实例1
int main()
{
 char a = 0xb6;
 short b = 0xb600;
 int c = 0xb6000000;

 if(a==0xb6)
     printf("a");
 if(b==0xb600)
     printf("b");
 if(c==0xb6000000)
     printf("c");

 return 0;
}

        在表达式a==0xb6,b==0xb600 执行前都需要对a,b进行整型提升,但是c本身就是int类型所以它不需要进行提升。a,b进行整型提升之后,都变成了负数,所以表达式a==0xb6,b==0xb600的结果为假,而c本身是不动的,所以表达式c==0xb6000000位真,所以程序输出的结果为:

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

        在实例2中的c只要参与表达式运算,就会发生整型提升,表达式+c时,c就会发生整型提升。表达式-c,也是同样的效果。所以sizeof(+c)和sizeof(-c)就都是4个字节。而sizeof(c)是一个字节。

        9.2 算术转换

        在运算过程中,如果某个操作数的各个操作数属于不同类型,那么除非其中一个操作数的类型转换位另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

        这里我们引入一个例子:

#include <stdio.h>
int i; 
int main()
{
    i--;
    if (i > sizeof(i))
    {
        printf(">\n");
    }
    else
    {
        printf("<\n");
    }
    return 0; 
}

        让我们来分析一下:全局变量i未进行初始化,所以它的默认值为0;进入主函数后i--,i的值变为-1,在内存中存储的值为负数的补码形式(0xFFFF)。sizeof(i)的值为4,初学者认为-1< 4,那么程序的输出应该为 '<';让我们来运行一下:

        结果恰恰相反,那么究竟是怎么一回事嘞?原来sizeof(i)返回的数据类型为无符号整形,它的等级高于整形,所以在参与运算前,i进行了算术转换,从原来的整型转换为无符号整型。内存中的(0xFFFF)被当成正数,所以它的值大于4。故输出 '>'。

10、操作符的属性

        复杂表达式的求值有三个影响的因素。         1. 操作符的优先级         2. 操作符的结合性         3. 是否控制求值顺序。         两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。         各位看官老爷们,今天要分享的内容到这里就结束了。希望上述的内容对大家有所帮助! 如有帮助请一键三连,万分感谢。

        

标签:操作数,语言,int,操作符,整型,sizeof,表达式
From: https://blog.csdn.net/qq_70199082/article/details/143082861

相关文章

  • C语言 【操作符(上)】
        最开始提到C语言操作符,我还是有一些不屑的,这玩意有啥学的呀?今天静下心来阅读学习了一下操作符部分的知识,这部分还真得认真学习学习!下面我将操作符中一些比较关键的点进行罗列和详细说明。一来帮助我加深理解,二来希望能帮助到有缘点击进来的读者。1、算术操作符:+ ......
  • C语言经典游戏代码大全(珍藏版)
    前言发现很多朋友都想要一些小项目来练手,却找不到从哪里寻找,给大家整理了游戏项目开发源代码汇总。一、最经典游戏之俄罗斯方块#include<iostream>#include<math.h>#include<Windows.h>#include<conio.h>#include<ctime>usingnamespacestd; enumDIR{   UP......
  • 第四届教育,语言与艺术国际学术会议 2024 4th International Conference on Education,
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍第四届教育,语言与艺术国际学术会议(ICELA2024)将于2024年11月2......
  • Linux C语言TCP协议实战
    文章目录1.TCP简介2.搭建框图3.相关函数介绍3.1socket函数3.2bind函数3.3listen函数3.4accept函数3.5connect函数3.6send函数3.7recv函数3.8其他函数4.实战4.1一对一模型4.1.1server.c4.1.2client.c4.1.3终端结果4.2多进程模型4.2.1server.c4.2.2cl......
  • 汉诺塔问题和青蛙跳台阶问题(c语言)
     这俩道题都是利用到了函数递归的思想,其中汉诺塔问题较难理解,青蛙跳台阶则较简单汉诺塔问题题述:设有三根柱子分别时A,B,C,在A柱子上放着n个盘子,每个盘子大小不一样,从下往上盘子大小依次减小,要求将A柱子上的盘子移动到C柱,且不改变盘子顺序(由大往小排序)。规则:1.一次只能......
  • R语言中$和@是什么意思
    https://www.cnblogs.com/huaan011/p/18348912https://docs.pingcode.com/ask/180671.html  R语言中$和@是什么意思R语言中的$和@运算符在数据操作中扮演着至关重要的角色。$用于提取或替代列表、数据框(dataframe)中的列(分量)、@则用于访问S4对象中的插槽(slot)。具体来说,$使我......
  • 【C语言】动态内存管理(上)
    本篇博客将讲解以下知识点:(1)为什么要有动态内存分配(2)malloc和free1、为什么要有动态内存分配我们已经掌握的内存开辟方式有:intval=40;//向内存中申请4个字节空间存储valchararr[10];//向内存申请10个字节空间 上述的开辟空间的方式有两个特点:(1)空间的开辟......
  • 【C语言】strncat、strncmp、strstr函数讲解
    本篇博客将讲解函数:strncat、strncmp、strstr函数注意:使用strncat、strncmp、strstr函数时要包含头文件:string.h1、strncat函数的使用(是从目标空间中第一个的‘\0’位置开始追加的)strncat函数原型: char*   strncat(char*destination,  const char* sourc......
  • 5步轻松上手!零基础也能掌握Go语言编程
    你是不是经常听到Go语言(Golang)在技术圈的讨论,却不知道如何开始?Go语言凭借其简洁、高效和并发处理能力,成为越来越多开发者和公司的首选。特别是在高并发场景如微服务、分布式系统中,Go的优势尤为突出。作为一门对初学者友好的语言,即便你没有编程基础,也可以通过以下5个简单步骤......
  • c语言语法(76-79)10.19
    一.定义数组1.数组定义:2.数组的特点:补:数组内部的特点:左值是读,右值是写3.数组的下标:从0开始计数4.有效的下标范围:从0开始到数组的大小-1的范围当出现以下标志表示数组的下标越界:eg.此代码中的10超过了有效下标9,所以无效会报错二.数组的例子1.eg题目:代码:三.......