Cpp知识点系列-类型转换

news2024/11/24 2:53:18

前言

在做题的时候发现了需要用到类型转换,于是在这里进行了简单的记录。

历史原因,慢慢整理着发现类型转换也能写老大一篇文章了。又花了时间来梳理一下就成了本文了。

cpp

之前使用的环境是DEV-C++ 5.4,而对应的GCC版本太低了。支持c++11需要GCC版本至少达到4.8.1才可以!

1

数据类型和运算符

四种基本数据类型

基本数据类型是分为四种的,分别是整型,浮点型,字符型和布尔型

四种基本类型

image-20201113122319295

从表2-1中可以看到,C++的基本数据类型有bool(布尔型)、char(字符型)、 int(整型),float(浮点型,表示实数) , double(双精度浮点型,简称双精度型)。除了bool型外,主要有两大类:整数和浮点数。

因为char型从本质上说也是整数类型,它是长度为1个字节的整数,通常用来存放字符的ASCII码。

其中关键字signed和 unsigned,以及关键字short 和long被称为修饰符

细节ISOC++标准并没有明确规定每种数据类型的字节数和取值范围,它只是规定它们之间的字节数大小顺序满足:

(signed/unsigned)char ≤ (unsigned)short ≤ (unsigned)int ≤ (unsigned) long

不同的编译器对此会有不同的实现。

面向32位处理器(IA-32)的C++编译器,通常将intlong两种数据类型皆用4个字节表示。

但一些面向64位处理器(IA-64或x86-64)的C++编译器中, int也是用4个字节表示, 但是long8个字节表示。

结构体类型

struct A {
 char c1;
 short s1;
};

这里不是主要说这个应用,而是分配字节的大小问题。

基础数据类型的字节长度很明显:

类型长度(字节)
char1
short2
int4
long4
float4
double8
long long8

然而,结构体的计算方式不是类似数组类型那样简单的累计,而是需要考虑到系统在存储结构体变量时的地址对齐问题

偏移量概念:偏移量指的是结构体变量中成员的地址和结构体变量地址的差

在实际中,存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则

(1)结构体变量中某成员的偏移量必须是该成员字长大小的整数倍(0被认为是任何数的整数倍)

(2)结构体大小必须是所有成员大小的公倍数。(按顺序以已经存在的最大字长为单位)

结构体大小等于最后一个成员的偏移量加上最后一个成员的大小

故而有以下几个例子:

struct A {
 char c1;//偏移量0 字长1
 char c2;//0+1=1 1
 double d1;//(1+1=2)+6=8 8
 //8+8=16是1,8的公倍数
};
struct B {
 char c1;//0 1
 double d1;//1+7=8 8
 char c2;//8+8=16  1
 //16+1=17不是1,8的公倍数,要扩到24才是
};
struct C {
 char c1;//0 1
 float f1;//1+3 4
 char c2;//8 1
 //8+1=9不是1,4的公倍数,扩到12才是
};

枚举类型

其实枚举类型的应用是很简单的,不过我个人应用的话更倾向于使用map类。

类似结构体的语法。

enum 枚举类型名 {变量值列表};

附上例子。

#include <iostream>

using namespace std;
enum GameResult {
    WIN,LOSE,TIE,CANCEL
}; //下标依次为0,1,2,3
int main() {
    GameResult result;//声明变量时,可以不写关键字enum
    enum GameResult omit = CANCEL;//也可以在类型名前写enum

    for (int count = WIN; count <= CANCEL; count++) {//枚举类型隐含类型转换为整型
        result = GameResult(count);//整型显式类型转换为枚举类型
        if (result == omit)
            cout << "The game was cancelled" << endl;
        else {
            cout << "The game was played ";
            if (result == WIN)
                cout << "and we won ! ";
            if (result == LOSE)
                cout << "and we lost . ";
            cout << endl;
        }
    }
    return 0;
}

注意:

WIN等是常量,不能对它们赋值。作用范围(严格来说是 main() 函数内部)内不能再定义与它们名字相同的变量。

枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值(cpp->.i),枚举在编译阶段将名字替换成对应的值(.i->.s)。所以不能对枚举类型使用指针

可以再复习一下CPP编译运行的过程就更容易理解了。

ASCII表

建议直接访问在线网页:https://zh.cppreference.com/w/cpp/language/ascii

有以下四个需要注意:

  • 空格 32

  • ‘0’ 48

  • ‘A’ 65

  • ‘a’ 97

    image-20201113125805916

运算符优先级

优先级运算符说明结合性
1::范围解析(命名空间)自左向右
2++ --后缀自增/后缀自减
()括号
[]数组下标
.成员选择(对象)
−>成员选择(指针)
3++ --前缀自增/前缀自减自右向左
+ −加/减
! ~逻辑非/按位取反
(type)强制类型转换
*取指针指向的值
&某某的地址
sizeof某某的大小
new, new[]动态内存分配/动态数组内存分配
delete, delete[]动态内存释放/动态数组内存释放
4.* ->*成员对象选择/成员指针选择自左向右
5* / %乘法/除法/取余
6+ −加号/减号
7<< >>位左移/位右移
8< <=小于/小于等于
> >=大于/大于等于
9== !=等于/不等于
10&按位与
11^按位异或
12|按位或
13&&与运算
14||或运算
15?:三目运算符自右向左
16=赋值
+= −=相加后赋值/相减后赋值
*= /= %=相乘后赋值/相除后赋值/取余后赋值
<<= >>=位左移赋值/位右移赋值
&= ^= |=位与运算后赋值/位异或运算后赋值/位或运算后赋值
17throw抛出异常
18逗号自左向右

关系运算符

image-20201113140859803

逻辑运算符

操作数在计算之前隐式转换为类型 bool,结果的类型为 bool。

非!

使用方式为从右向左

如果已转换的操作数是 false,则结果是 true;

如果已转换的操作数是 true,则结果是 false。

与&&

使用方式为从左至右。

如果所有的操作数都为 true,则逻辑“与”运算符 (&&) 返回布尔值 true,否则返回 false。

第一个操作数将完全计算,并且完成所有副作用,之后才会继续计算下一个逻辑“与”表达式。

如果第一个操作数的计算结果为 true(非零),才计算第二个操作数。

或||

使用方式为从左至右。

如果任一操作数为 true,则逻辑“或”运算符 (||) 返回布尔值 true;否则返回 false。

第一个操作数将完全计算,并且完成所有副作用,之后才会继续计算下一个逻辑“或”表达式。

仅当第一个操作数的计算结果为 false (0) 时,才计算第二个操作数。

算术运算符

加减乘除

  • 当两个数都是整数时,运算结果也是整数。

  • 当有一个数是小数时,运算结果是小数。

  • 对于除法,如果两个整数相除但又不能整除,则只保留整数部分,这跟将小数赋值给整数类型是一个道理。

取余

“%”是取余运算,只能用于整型操作数,表达式a%b的结果是a被b除的余数。“%”的优先级与“/”相同。

逗号运算符

在C++中,逗号也是一个运算符,它的使用形式为:表达式1,表达式2 求解顺序为先求解i,再求解⒉,最终结果为表达式2的值。

int x=0;
int y=(x=x+3,4,545);
cout<<y<<" "<<x;
// 545 3

结果是545 3

类型转换

C++基本类型(int,char等)的指针之间不能含有隐式转换,必须要用显示转换!

int类型四舍五入

因为题目要求保留一位有效数字,所以就先把这个数乘十,按照正负加减零点五,两次强制类型转换后,再除以十即可。今后碰见四舍五入问题以此类推!

double dou=39.65;
dou = (double)((int)(dou*10 + (dou<0?-0.5:0.5)))/10;

int和char

int转char之前,先将运算式中的每个字符都转换成ASCII码值,再进行计算,根据结果转换为字符(数值为该字符对应的ASCII码值)。

以下代码为例,其中c4的结果符合我们的预期要求。

void int_to_char(){
    int i = 5;

    char c1 = i;                  // 5 '\x05'无法打印
    char c2 = i - 0;              // 5 '\x05'无法打印
    char c3 = i - '0';            // -43 '\xd5'打印乱码
    char c4 = i + '0';            // 53 '5'可打印
    cout<<c4;
}

char转int之前,先将运算式中的每个字符都转换成ASCII码值,再进行计算。

以下代码为例,其中i3的结果符合我们的预期要求。

void char_to_int(){
    char c = '0';

    int i1 = c;                    // 48
    int i2 = c - 0;                // 48
    int i3 = c - '0';              // 0
    int i4 = c + '0';              // 96
    cout<<i3;
}

int和string

void int_to_string() {
    int a = 100;
    string b = "";
    b = to_string(a);//string库,但需要c++11的支持
    cout<<b;
}

活着是另外一个方式

void string_to_int() {
    int a = 1;
    string b = "100abbc";
    a = atoi(b.c_str());//标准库,但是会忽略字符串中的字母,只保留数字
    cout<<a<<endl;
    a = stoi(b);//string库,但需要c++11的支持
    cout<<a;
}

如果不支持c++11的话,可以参考博客。

#include<sstream>
#include<string>
int a = 10;
stringstream ss;

ss.str("");//重复调用一个对象的话要清空,clear函数只是重置状态。
ss << a;
string str = ss.str();

int和bool

int和bool类型之间存在隐式转换.

注意,直接输出bool类型的时候,控制台上结果为1或0

需要加上一个标志符来输出true或者false

void bool_to_int() {
    bool a = true, b = false;
    cout << "a=" << a << " , b=" << b << endl;
    cout << "a=" << boolalpha << a << " , b=" << b << endl;
}

image-20220828230919429

string、char *、char[]

string转char*

主要有三种方法可以将string转换为const char*类型,分别是:data()、c_str()、copy()。

  • data()方法

void stringt_to_char_data() {
    string str = "hello";
    const char *p1 = str.data();//不可修改
    cout << p1 << endl;

    char *p2 = (char *) str.data();//可修改
    p2[1]++;
    cout << p2;
}
  • c_str()方法

void stringt_to_char_c_str() {
    string str="world";
    const char *p1 = str.c_str();//不可修改
    cout << p1 << endl;

    char * p2=(char*)str.c_str();//可修改
    p2[1]++;
    cout << p2;
}
  • copy()方法

    可能会报安全性错误,自行解决即可。注意手动加结束符!!!

void stringt_to_char_copy() {
    string str = "hmmm";
    char p[10];
    str.copy(p, 3, 0);//这里3代表复制几个字符,0代表复制的位置,
    p[3] = '\0';//注意手动加结束符!!!
    cout << p;
}

char * 转string

可以直接赋值。

string s;
char *p = "helloworld";
s = p;

string转char[]

for循环遍历输入。

string pp = "helloworld";
char p[20];
int i;
for( i=0;i<pp.length();i++)
    p[i] = pp[i];
p[i] = '\0';                  //手动添加结束符

char[]转string

可以直接赋值。

string s;
char p[20] = "helloworld";
s = p;

char[]转char*

可以直接赋值。

char pp[20] = "helloworld";
char* p = pp;
12

char*转char[]

主要有两种方法可以将char*转换为char[]类型,分别是:strcpy()、循环遍历。

  • strcpy()方法

可能会报安全性错误,自行解决即可。

char arr[20];
char* tmp = "helloworld";
strcpy(arr, tmp);
  • 循环遍历

char arr[20];
char* tmp = "helloworld";
int i = 0;
while (*tmp != '\0')
 arr[i++] = *tmp++;
arr[i] = '\0';             //手动添加结束符

进制转换

int main() {
    int PrintVal = 9;
    /*按整型输出,默认右对齐*/
    printf("%d\n", PrintVal);
    /*按整型输出,补齐4位的宽度,补齐位为空格,默认右对齐*/
    printf("%4d\n", PrintVal);
    /*按整形输出,补齐4位的宽度,补齐位为0,默认右对齐*/
    printf("%04d\n", PrintVal);

    /*按16进制输出,默认右对齐*/
    printf("%x\n", PrintVal);
    /*按16进制输出,补齐4位的宽度,补齐位为空格,默认右对齐*/
    printf("%4x\n", PrintVal);
    /*按照16进制输出,补齐4位的宽度,补齐位为0,默认右对齐*/
    printf("%04x\n", PrintVal);

    /*按8进制输出,默认右对齐*/
    printf("%o\n", PrintVal);
    /*按8进制输出,补齐4位的宽度,补齐位为空格,默认右对齐*/
    printf("%4o\n", PrintVal);
    /*按照8进制输出,补齐4位的宽度,补齐位为0,默认右对齐*/
    printf("%04o\n", PrintVal);
    return 0;
}

结果如下:

例子

运算符例子1

#include <iostream>

#define endl '\n'
using namespace std;

int main() {
    int a, b, c, x, y;
    a = 1;
    b = 2;
    c = 0;
    cout << a++ - 1 << endl;//后缀自增运算符优先级大于加减运算符 
    cout << (a && b || !c) << endl;//a和b相与结果为真 
    cout << b / ++a << endl;//2除以3商0 
    x = ++a || ++b && ++c;//或运算被a=4短路 
    cout << a << b << c << x << endl;
    a = b = c = -1;
    y = ++a && ++b && ++c;//与运算被a=0短路 
    cout << a << b << c << y << endl;
    return 0;
}

image-20201113103823373

运算符例子2

int main() {
    int a = 4, b=3,c=2,d=1;
    int x, y = 0;
    x=a<b ? a+1 : c<d ? c+1 : d+1;//先判断a<b,再判断c<d,最后返回d+1 
    cout <<x <<endl;
    cout <<(a+ b, b + c,c+ d) <<endl;//返回最后一个c+d
    y += a+=b+= c+ d;//从右向左 
    cout<<y<<endl;
    return 0;
}

image-20201113114428361

感谢

源码文件

gitee:https://gitee.com/JunKuangKuang/KeenCPPTest-all/tree/main/basic/transition

github:https://github.com/JunKuangKuang/KeenCPPTest-all/tree/main/basic/transition

更新记录

2022.8.28更新:clang-1316.0.21.2.5,诶嘿嘿嘿……

忘了啥时候更新的了:重新使用了TDM-GCC 9.2 真香!

更早以前:后来我重新下载了新版本的,GCC更新为4.9的了。现在不让下载4.9的版本了,又重新下载了6版本使用。

感谢

感谢现在努力的我

  1. 参考《C++语言程序设计(第4版)》(郑莉,董渊)

  2. C++ int转string的多种方式

  3. c++中int与char相互转换

  4. printf按8进制、10进制、16进制输出以及高位补0

  5. C++逻辑运算符基本用法整理

  6. C++运算符优先级表

  7. c++中string、char *、char相互转换

  8. C++解决sizeof求结构体大小的问题

  9. C语言枚举类型

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

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

相关文章

【CSS】重点知识梳理,这样上手无压力

推荐前端学习路线如下&#xff1a; HTML、CSS、JavaScript、noodJS、组件库、JQuery、前端框架&#xff08;Vue、React&#xff09;、微信小程序和uniapp、TypeScript、webpack 和 vite、Vue 和 React 码源、NextJS、React Native、后端内容。。。。。。 CSS定义&#xff1a; …

docker入门到精通一文搞定

文章目录前言一、Docker概述1.Docker为什么会出现&#xff1f;2.Docker相比VM技术3.Docker 能做什么&#xff1f;3.1 比较Docker和虚拟机技术的不同&#xff1a;3.2 DevOps (开发、运维)&#xff1a;4个特点二、Docker安装1.dokcer架构图&#xff1a;2.Docker基本组成&#xff…

python+django体质测试数据分析及可视化设计

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 B/S架构 4 本选题则旨在通过标签分类管理等方式&#xff0c;实现管理员&#xff1a;管理员&#xff1a;首页、个…

11.前端笔记-CSS盒子模型-外边距margin

1、margin 1.1 margin的语法 盒子与盒子之间的距离 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewpor…

linux 系统的磁盘 mbr 转gpt方法

linux磁盘用fdisk格式化挂盘的格式都为mbr, 不支持大于2T的磁盘扩容&#xff0c;需要用parted转化。 查询磁盘格式 输入&#xff1a; fdisk -l 看Disk label type 的值&#xff0c;是dos 的为mbr 是gpt的为gpt 当前&#xff0c;因挂盘时&#xff0c;用的fdisk方式选gpt,挂…

基于STM32的u8g2移植以及学习

实验硬件&#xff1a;STM32F103C8T6&#xff1b;0.96寸OLED&#xff08;12864&#xff09; U8g2库开源网址&#xff1a;https://github.com/olikraus/u8g2 一、u8g2库知识 1.1 什么是u8g2&#xff1f; U8g2是嵌入式设备的单色图形库。主要应用于嵌入式设备&#xff0c;包括我…

正大国际期货:投资外盘期货如何运用K线图中十字星形态?

很多人都明白&#xff0c;做外盘期货需要学会看线图。那么K线图上面的一根两根的柱子代表的什么意思呢&#xff1f;其中星星点点的十字星又是什么意思&#xff1f;下面正大IxxxuanI详细给大家讲解一下&#xff01; 1、什么是多头十字星形态&#xff1f; 多头十字星是一种经典…

KEITHLEY 吉时利2601B源表产品技术参数

KEITHLEY 2601B 吉时利 2601B 源表让您可以比以前更快、更轻松、更经济地进行精密直流、脉冲和低频交流源测量测试。Keithley 2601B 通过结合以下特性&#xff0c;为 IV 功能测试提供竞争产品 2 到 4 倍的测试速度&#xff1a; 吉时利的高速第三代源测量单元 (SMU) 设计 嵌…

【Python】八、函数的使用

文章目录实验目的一、定义函数二、调用函数三、参数的传递和函数的返回值四、编写函数&#xff0c;输入不同的参数&#xff0c;绘制不同的科赫曲线参考代码实验截图实验目的 掌握函数的定义和调用&#xff1b;掌握函数的用法&#xff1b;理解递归&#xff1b;培养学生动手查阅资…

开源:分享4个非常经典的CMS开源项目

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

Spark系列之Spark安装部署

title: Spark系列 第二章 Spark安装部署 2.1 版本选择 下载地址&#xff1a; https://archive.apache.org/dist/spark 四大主要版本 Spark-0.X Spark-1.X&#xff08;主要Spark-1.3和Spark-1.6&#xff09; Spark-2.X&#xff08;最新Spark-2.4.8&#xff09; Spark-3.x&a…

降级、熔断和限流———一看就会

设定&#xff1a;A上游系统、B本系统、C下游系统 服务降级 服务降级是从整个系统B的负荷情况出发和考虑的&#xff0c;对某些负荷会比较高的情况&#xff0c;为了预防某些功能&#xff08;业务场景&#xff09;出现负荷过载或者响应慢的情况&#xff0c;在B其内部暂时舍弃对一…

【Mybatis编程:统计相册表中的数据的数量】

目录 1. 书写SQL语句 2.在AlbumMapper.java接口中添加抽象方法 3. 在AlbumMapper.xml中配置SQL语句 4. 在AlbumMapperTests.java中编写并执行测试 1. 书写SQL语句 需要执行的SQL语句大致是&#xff1a; select count(*) from pms_album 在设计抽象方法时&#xff0c;如果要…

【三维重建补充知识-0】视差、深度概念及其转换

一、基本概念 把手指放在眼前&#xff0c;分别闭上左、右眼&#xff0c;我们会发现手指与后边物体的相对位置是不同的&#xff0c;也即两眼所识别的两幅图像之间存在视觉差异&#xff0c;我们通过“视差”这一概念来表示这种差别。 该过程也可以通过两个处于同一平面的相机来模…

Ajax学习:Ajax请求基本操作

点击按钮&#xff0c;发送请求&#xff08;前端页面和服务端页面信息交流 但是不刷新页面&#xff09; 注意使用谷歌浏览器 服务器端打开&#xff1a;使用nodemon //1、导入express const expressrequire(express) //2、创建应用对象 创建web服务器 const appexpress() //3、…

软考高级系统架构师_计算机组成与结构02_高速缓存_磁盘结构_输入输出技术_总线结构_可靠性_---软考高级系统架构师005

1.Cache是Cpu与主存储器之间的速度比主存储器要块10倍左右,因为cpu用的说主存储器中的地址, 而cpu速度很快,主存储器速度慢,所以中间加了这个cache,那么这里就涉及到,怎么把cache地址转化成主存储器的地址,cpu使用地址的时候首先访问主存储器地址,但是访问的是cache,所以这个时…

第十二周学习总结 Progress Lack

关于计划的制定 FlowUs计划链接&#xff1a; 点击我进入计划 发现不足&#xff1a;首先&#xff0c;制定计划经验不足&#xff0c;制定计划应该是具体的、有任务量、完成时间。 其次任务应该是可衡量的&#xff08;比如&#xff0c;我阅读李升波老师的网站文章&#xff0c;应…

【WAX链游】发布一个免费开源的Alien Worlds【外星世界】合约脚本TLM

前言 《链游Farmers World【农民世界】爆火&#xff0c;发布一个免费开源的脚本》 在之前的文章中&#xff0c;我们分享了一个开源的农民世界(Farmers World)脚本 【OpenFarmer】&#xff1a;https://github.com/encoderlee/OpenFarmer 经过这段时间以来的不断学习&#xff…

【HTML】重点知识内容~快速上手

推荐前端学习路线如下&#xff1a; HTML、CSS、JavaScript、noodJS、组件库、JQuery、前端框架&#xff08;Vue、React&#xff09;、微信小程序和uniapp、TypeScript、webpack 和 vite、Vue 和 React 码源、NextJS、React Native、后端内容。。。。。。 HTML基本结构&#xff…

QT教程:QSortFilterProxyModel代理实现自定义排序、联合过滤

1. QsortFilterProxyModel介绍 QsortFilterProxyModel类用来为model和view之间提供强大的排序和过滤支持。将模型排序或者过滤后在视图上显示,并且无需对模型中的数据进行任何转换&#xff0c;也无需对模型在中数据进行修改。 比如: 对某列筛选带有”xxx”的关键字出来.并支持…