C语言入门系列:数据类型转换

news2025/2/8 14:21:14

文章目录

  • 一,自动类型转换
    • 1,赋值运算
      • 1.1,浮点数赋值给整型变量-不安全
      • 1.2,整数赋值给浮点数变量-安全
      • 1.3,窄类型赋值给宽类型-安全
      • 1.4,宽类型赋值给窄类型-不安全
    • 2,混合类型的运算
      • 2.1,整形和浮点数混合
      • 2.2,不同的浮点数类型混合
      • 2.3,不同的整数类型混合
    • 3,整数类型的运算
    • 4,函数
  • 二,强制类型转换

在这里插入图片描述

当不同数据类型的数据出现在同一个表达式中时,就会涉及数据类型转换,C语言中的数据类型转换有两种:

  • 自动类型转换
  • 强制类型转换

类型转换可能是安全的,即不会丢失数据;也可能是不安全的,即出现丢失数据的情况。

窄类型转换为宽类型,是安全的,不会丢失数据。

宽类型转换为窄类型,是不安全的,虽然不是百分百丢失数据,但有丢失数据的可能。

一,自动类型转换

自动类型转换是指在特点情况下,编译器将一种数据类型自动转换为另一种类型,自动类型转换可能是安全的,也可能是不安全的,即可能出现数据丢失。

1,赋值运算

赋值运算符左右两边的数据类型不一致时,会以变量的类型为准,将右边的值转成变量的类型。

1.1,浮点数赋值给整型变量-不安全

浮点数赋予整型变量时,C语言的转换过程简单粗暴,保留整数部分,丢弃小数部分。

int x = 3.14159627;

如上,变量x被声明为整型,然后赋一个double类型值。

编译器会把3.14159627转为整形,小数部分0.14159627会被丢弃(注意,不是四舍五入),保留整数3,3被赋值给变量x,因此变量x的值是3。

显然,这种情况下的自动类型转换导致数据丢失,是不安全的类型转换,我们在编写代码时,要避免类似的赋值语句,左右两边的类型一致才是最佳实践。

1.2,整数赋值给浮点数变量-安全

整型赋值给浮点数变量时,会自动转为浮点数。

float y = 12 * 2;

上面示例中,变量y的值不是24,而是24.0,因为等号右边的整数自动转为了浮点数。

C语言中的浮点数遵循了IEEE 754标准,使用科学计数法来存储浮点数,其数组范围被整形要大得多,所以整形赋值给浮点数,不会出现数据丢失,是安全的自动类型转换。

1.3,窄类型赋值给宽类型-安全

字节宽度较小的整数类型,赋值给字节宽度较大的整数变量时,会发生类型提升,即窄类型自动转为宽类型。

比如,char或short类型赋值给int类型,会自动提升为int。

char x = 100;
int i = x + y;

上面示例中,变量x的类型是char,由于赋值给int类型,所以会自动提升为int。

1.4,宽类型赋值给窄类型-不安全

字节宽度较大的类型,赋值给字节宽度较小的变量时,会发生类型降级,自动转为后者的类型。这时可能会发生截断,系统会将移除的高位二进制,从而出现意料之外的情况。

int i = 321;
char ch = i; // ch 的值是 65 (321 % 256 的余值)

上面例子中,变量ch是char类型,宽度是8个二进制位。

变量i是int类型,将i赋值给ch,后者只能容纳i(二进制形式为101000001,共9位)的后八位,前面多出来的二进制位被丢弃,保留后八位就变成了01000001(十进制的65,相当于字符A)。

之前介绍的浮点数赋值给整型变量,也属于宽类型自动转换为窄类型,也会发生截断,丢弃小数部分。

double pi = 3.14159;
int i = pi; // i 的值为 3

上面示例中,i等于3,pi的小数部分被截去了。

2,混合类型的运算

不同类型的值进行混合计算时,必须先转成同一个类型,才能进行计算。转换规则如下:

2.1,整形和浮点数混合

整数与浮点数混合运算时,整数转为浮点数类型,与另一个运算数类型相同。

3 + 1.2 // 4.2

上面示例是int类型与float类型的混合计算,int类型的3会先转成float的3.0,再进行计算,得到4.2。

2.2,不同的浮点数类型混合

运算时,宽度较小的类型转为宽度较大的类型,比如float转为double,double转为long double。

2.3,不同的整数类型混合

运算时,宽度较小的类型会提升为宽度较大的类型。

比如short转为int,int转为long等,有时还会将带符号的类型signed转为无符号unsigned。

下面例子的执行结果,可能会出人意料。

int a = -5;
if (a < sizeof(int)do_something();

上面示例中,变量a是带符号整数,sizeof(int)是size_t类型,这是一个无符号整数。

按照规则,signed int 自动转为 unsigned int,所以a会自动转成无符号整数4294967291(转换规则是-5加上无符号整数的最大值,再加1),导致比较失败,do_something()不会执行。

所以,最好避免无符号整数与有符号整数的混合运算。因为这时 C 语言会自动将signed int转为unsigned int,可能不会得到预期的结果。

3,整数类型的运算

两个相同类型的整数运算时,或者单个整数的运算,一般来说,运算结果也属于同一类型。

但是有一个例外,宽度小于int的类型,运算结果会自动提升为int。

unsigned char a = 66;

if ((-a) < 0) printf("negative\n");
else printf("positive\n");

上面示例中,变量a是 unsigned char 类型,这个类型不可能小于0,但是-a不是 unsigned char 类型,会自动转为 int 类型,导致上面的代码输出 negative。

再看下面的例子。

unsigned char a = 1;
unsigned char b = 255;
unsigned char c = 255;

if ((a - 5) < 0) do_something();
if ((b + c) > 300) do_something();

上面示例中,表达式a - 5和b + c都会自动转为 int 类型,所以函数do_something()会执行两次。

4,函数

函数的参数和返回值,会自动转成函数定义里指定的类型。

int dostuff(int, unsigned char);

char m = 42;
unsigned short n = 43;
long long int c = dostuff(m, n);

上面示例中,参数变量m和n不管原来的类型是什么,都会转成函数dostuff()定义的参数类型。

下面是返回值自动转换类型的例子。

char func(void) {
  int a = 42;
  return a;
}

上面示例中,函数内部的变量a是int类型,但是返回的值是char类型,因为函数定义中返回的是这个类型。

二,强制类型转换

最佳实践是,我们在编写代码时,应该避免自动类型转换,因为自动类型转换可能导致出现意料之外的情况。

代码的行为始终在程序员的预料之中,是程序员必须追求的目标。

对于必不可少的类型转换,最好是使用强制类型转换

强制类型转换是指在一个值或变量的前面,使用圆括号指定类型(type),称之为casting。

(unsigned char) ch

上面示例将变量ch转成无符号的字符类型。

char c = (char)266;

上面示例中,(char)将266强制转换为char类型。

首先,虽然从语法上看,这种转换是没有必要的,因为对于赋值运算来说,编译器会把右边的值自动转换为左边的类型。但是,这样的代码是我们推荐的写法,更直观,便于阅读。

其次,把整型266强制转换为char类型,会出现数据截断,导致部分数据丢失,但由于这是我们意料之中的情况,就不会出现安全问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1850745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kotlin 中的内联函数

1 inline 内联函数&#xff1a;消除 Lambda 带来的运行时开销。 举例来说&#xff1a; fun main() {val num1 100val num2 80val result num1AndNum2(num1, num2) { n1, n2 ->n1 n2} }fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int …

【自撰写】【国际象棋入门】第8课 国际象棋残局基础

第8课 国际象棋残局基础 一、残局的特点 残局是棋局的最后&#xff08;收尾&#xff09;阶段&#xff0c;虽然此时棋盘上的子力已经所剩无几&#xff0c;但依照不同的局面分类&#xff0c;残局中存在着许多有意思的变化&#xff0c;初始局面中的细小变化也可能引发到截然不同…

Redis源码学习:ziplist的数据结构和连锁更新问题

ziplist ziplist 是 Redis 中一种紧凑型的列表结构&#xff0c;专门用来存储元素数量少且每个元素较小的数据。它是一个双端链表&#xff0c; 可以在任意一端进行压入/弹出操作&#xff0c;并且该操作的时间复杂度为O(1)。 ziplist数据结构 <zlbytes><zltail>&l…

期货交易豆粕品种详细分析

文章目录 1、豆粕期货标准&#xff08;2024年6月22号数据&#xff09;2、豆粕是什么3、豆粕1、5、9合约区别4、影响豆粕的价格因素1、大豆的供应情况。2、豆粕的季节性3、油粕比&#xff08;豆油和豆粕的价格关系 &#xff09; 5、美国大豆的生产/库存炒作6、豆粕双方&#xff…

Linux中tar压缩与解压缩

TAR是Unix/Linux中常用的归档工具&#xff0c;它可以对文件或目录进行打包但不压缩&#xff0c;或者配合其他工具进行压缩。 压缩文件或目录 以下是一些基本的tar压缩命令&#xff1a; 1.压缩单个文件&#xff1a; tar -cvf archive.tar file1 2.压缩多个文件&#xff1a; t…

微软Edge浏览器全解析

微软Edge浏览器全解析(一) 解决浏览器的主页被篡改后无法通过浏览器的自带设置来恢复的问题 相信各位都有发现新买的联想电脑浏览器的主页设置不太满意,但从浏览器自带的设置上又无法解决此问题,网上找了许多方法都无济于事,特别对有着强迫症的小伙伴们更是一种煎熬。 通…

cocos 如何使用九宫格图片,以及在微信小程序上失效。

1.在图片下方&#xff0c;点击edit。 2.拖动线条&#xff0c;使四角不被拉伸。 3.使用。 其他 在微信小程序上失效&#xff0c;需要将packable合图功能取消掉。

26.2 Django简介

1. Python三大主流框架 根据当前的信息和流行度, Python的三大框架可以归纳为Django, Flask和FastAPI, 以下是对它们的清晰分点表示和归纳:* 1. Django: 一个高级的Python Web框架, 以快速开发和实用简洁的设计出名.它遵循MVC设计模式(但更倾向于MTV模式), 并提供了许多内置的…

实施高效冷却技术:确保滚珠丝杆稳定运行!

滚珠丝杆在运行过程中&#xff0c;由于摩擦、惯性力等因素&#xff0c;会产生一定的热量&#xff0c;当热量无法及时散发时&#xff0c;滚珠丝杆的温度就会升高&#xff0c;会直接影响滚珠丝杆的精度和稳定性&#xff0c;从而影响最终的产品质量。为了让滚珠丝杆保持应有的精度…

【博客719】时序数据库基石:LSM Tree的增删查改

时序数据库基石&#xff1a;LSM Tree的增删查改 LSM结构 LSM树将任何的对数据操作都转化为对内存中的Memtable的一次插入。Memtable可以使用任意内存数据结构&#xff0c;如HashTable&#xff0c;BTree&#xff0c;SkipList等。对于有事务控制需要的存储系统&#xff0c;需要在…

数据库设计文档编写

PS&#xff1a;建议使用第三种方法 方法1&#xff1a;使用 Navicat 生成数据库设计文档 效果 先看简单的效果图&#xff0c;如果效果合适&#xff0c;大家在进行测试使用&#xff0c;不合适直接撤退&#xff0c;也不浪费时间。 随后在docx文档中生成目标字段的表格&#xf…

dex文件结构(二):dex文件加载基本原理

return mClassLoader; } 1.3 ApplicationLoaders.getClassLoader public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent){ //Class.getSystemClassLoader返回的是一个PathClassLoader //baseParent是BootClassLoader ClassLoader basePare…

【仿真建模-anylogic】Network代码解析

Author&#xff1a;赵志乾 Date&#xff1a;2024-06-22 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 1. 类图 2. 代码解析 //************************核心字段************************* // Network所属的level private transient Leve…

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中&#xff0c;远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下&#xff0c;远程桌面服务使用的端口是3389。然而&#xff0c;出于安全考虑&#xff0c;许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…

乌班图Ubuntu 24.04 SSH Server 修改默认端口重启无效

试用最新的乌班图版本&#xff0c;常规修改ssh端口&#xff0c;修改完毕后重启sshd提示没有找到service&#xff0c;然后尝试去掉d重启ssh后查看状态&#xff0c;端口仍然是默认的22&#xff0c;各种尝试都试了不行&#xff0c;重启服务器后倒是端口修改成功了&#xff0c;心想…

AcWing算法基础课笔记——高斯消元

高斯消元 用来求解方程组 a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 … a n 1 x 1 a n 2 x 2 ⋯ a n n x n b n a_{11} x_1 a_{12} x_2 \dots a_{1n} x_n b_1\\ a_{21} x_1 a_{22} x_2 \dots a_{2n} x_n b_2\\ \dots \\ a…

陈好与王星越中戏传承

陈好与王星越&#xff1a;中戏传承&#xff0c;万人迷与未来之星在娱乐圈的星光璀璨中&#xff0c;我们时常被那些耀眼的明星所吸引&#xff0c;但你是否曾想过&#xff0c;他们背后的成长之路&#xff0c;是如何被一位位优秀的老师所指引的呢&#xff1f;今天&#xff0c;就让…

刷代码随想录有感(113):动态规划——爬楼梯plus

题干&#xff1a; 代码&#xff1a; #include<bits/stdc.h> using namespace std;int main(){int n,m;cin>>n>>m;vector<int>dp(n 1, 0);dp[0] 1;for(int j 0; j < n; j){for(int i 1; i < m; i){if(j > i)dp[j] dp[j - i];}}cout<&…

交互式知识库问答:一种结合大型语言模型的多轮交互方法

在当今信息爆炸的时代&#xff0c;人们每天都要处理海量的数据和信息。在这样的背景下&#xff0c;基于知识库的问答系统&#xff08;KBQA&#xff09;成为了一个重要的研究领域&#xff0c;它旨在使计算机能够理解自然语言提出的问题&#xff0c;并从结构化的知识库中检索出准…

以太坊==给合约转入/查询合约剩余/合约转给某账户/结构体/MAP

转入 必须要定义该函数&#xff0c;或者定义fallback // 接收以太币 receive() external payable {} // Corrected Line // SPDX-License-Identifier: MIT pragma solidity ^0.8.0;contract SimpleStorage {uint256 private storedData;// 事件&#xff0c;用于通知数据变更e…