C语言——隐式转换

简介: 这里小编给大家简单的补充一下,一些有关C语言的知识点

前言

这里小编给大家简单的补充一下,一些有关C语言的知识点


隐式转换

由于转换形式的不同类型转换这里一共分为整型提升和运算转换两种形式


1.整型提升

在了解整型提升之前,这里我们需要先了解一下截断这个概念,对于截断操作,这里我举个例子给大家简单的说明一下


这里我们举一个例子,这里char a=1,但是对于char存储的大小仅仅只是8字节,那么对于常量1,这里却是一个整型,占了32字节,那么为了存储这个变量我们这里就会发生截断操作,对于截断的规则如下:从低位开始,选取处该需要存储的字节大小。


也即是:



所以存储在变量a中也就是0 0  0 0  0 0 0 1。


那么整型提升又是什么呢?


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


整型提升的意义:

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

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

换为int或unsigned int,然后才能送入CPU去执行运算。


那么对于整型提升的具体过程又是怎么的呢?


这里我们以char类型给大家简单演示一下:



大家可能平时会见到这样的代码:


int main()
{
  char a = 127;
  char b = 3;
  char c = a + b;
  printf("%d", c);
  return 0;
}

这里我们先直接看结果:



大家都知道有符号得char类型得表示范围是-127~128,那么这里就不会出现存储130值的char类型,那么该又是怎么得到-126这个值的呢?


这里其实就发生了整型提升和截断的两个过程


首先我们进行运算就需要进行整型提升:


127的补码如下:


01111111


进行整型升后得到的是


00000000000000000000000001111111


3的补码是


00000011


整型提升后的值是:


00000000000000000000000000000011


然后我们把整型提升后的值进行相加得到:


00000000000000000000000010000010.


然后我们需要将其存入c,因为c是char类型,所以这里我们要对其进行截断操作,那么我们得到c的补码是:10000010。


然后我们对其进行打印操作,由于我们是将其按整型的形式打印出来,所以这里我们要进行整型提升,也就得到:11111111111111111111111110000010.


由于该是负数,这里我们就需要将其转化为原码输出,所以这里我们转换成原码后得到


10000000000000000000000001111110.


所以这里按二进制转十进制后,得到的值是:-126.


2.算数转换

对于小于整型的情况我们使用的是整型提升的方式,但是对于大于int的类型,我们采用的是算数转换的方式。那么对于算数转换的规则是:

int->unsigned int->long int->unsigned long int->float->double->long double


这里给大家简单举一个例子,这里我们使用到sizeof函数,这里有一点我们需要注意的是sizeof的返回值是unsigned int,那么下面我们直接看代码

int main()
{
  int i = -1;
  if (i < sizeof(i))
  {
  printf("haha");
  }
  else
  {
  printf("hehe");
  }
}

这里如果没有隐式转换,那么我们得到的值应该是haha,但是由于我们 i变量发生了隐式转换,遂于-1的无符号数,该是特别大的,所以我们这里的打印值应该是呵呵。


这里我们看运行结果:

相关文章
|
10月前
|
编译器 测试技术 C语言
【C语言航路外传】隐式转换与优先级的那点事(你程序总是出bug的一个重要原因)
【C语言航路外传】隐式转换与优先级的那点事(你程序总是出bug的一个重要原因)
80 0
|
存储 C语言
【C语言】隐式转换
本文讲解:C语言中的隐式转换。
|
8天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
11天前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
11天前
|
存储 C语言
C语言程序设计核心详解 第七章 函数和预编译命令
本章介绍C语言中的函数定义与使用,以及预编译命令。主要内容包括函数的定义格式、调用方式和示例分析。C程序结构分为`main()`单框架或多子函数框架。函数不能嵌套定义但可互相调用。变量具有类型、作用范围和存储类别三种属性,其中作用范围分为局部和全局。预编译命令包括文件包含和宏定义,宏定义分为无参和带参两种形式。此外,还介绍了变量的存储类别及其特点。通过实例详细解析了函数调用过程及宏定义的应用。
|
16天前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
16天前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
17天前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
1月前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
23 4
|
1月前
|
编译器 程序员 C语言
【C语言篇】从零带你全面了解函数(包括隐式声明等)(下篇)
⼀般情况下,企业中我们写代码时候,代码可能⽐较多,不会将所有的代码都放在⼀个⽂件中;我们往往会根据程序的功能,将代码拆分放在多个⽂件中。