前言 在做题的时候发现了需要用到类型转换,于是在这里进行了简单的记录。 历史原因,慢慢整理着发现类型转换也能写老大一篇文章了。又花了时间来梳理一下就成了本文了。 之前使用的环境是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++编译器,通常将int 和long 两种数据类型皆用4个字节表示。 但一些面向64位处理器(IA-64或x86-64)的C++编译器中, int 也是用4个字节表示, 但是long 用8个字节表示。结构体类型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 枚举类型名 {变量值列表}; 附上例子。#includeusing 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关系运算符 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< 如果不支持c++11的话,可以参考博客。
#include
#include 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-20220828230919429string、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] = " ";//注意手动加结束符!!! 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