【捡起C++】处理数据

【捡起C++】处理数据

面向对象的本质是设计并扩展自己的数据类型。

​ 为了把信息存储到计算机中,程序必须记录3个基本属性:

  • 信息将存储在哪里
  • 要存储什么值
  • 存储何种类型的信息
int braincount;
braincount = 5;
/*
	程序找到一块能存储整数的内存,将该内存标记为braincount,并将5复制到该内存单元中;然后,可在程序中使用braincount来访问该内存单元。
	这些语句没有告诉这个值将存储在内存的什么位置,但程序确实记录了这种信息。可以使用&运算符来检索braincount的内存地址。
*/
变量名

​ 以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。

整型short、int、long和long long

​ 不同位数的计算机下的长度有所不同。

  • short 至少 16位

  • int与short至少一样长

  • long至少32位,且至少与int一样长

  • long long至少64位,且至少与long一样长

    16位的int的取值范围为 -32768 到 +32767。

    sizeof运算符可返回类型或变量的长度,单位为字节。 运算符是内置的语言元素,对一个或多个数据进行运算,并生成一个值。

​ “字节”的含义依赖于硬件,在一个系统中,两字节的int可能是16位,另一个系统中可能是32位。

​ 头文件 climits包含了关于整型限制的信息。例如INT_MAX为int的最大取值,CHAR_BIT为字节的位数。

#include<iostream>
#include<climits>
using namespace std;
int main(){
  int n_int = INT_MAX;
  short n_short = SHRT_MAX;
  long n_long = LONG_MAX;
  long long n_llong = LLONG_MAX;

  cout << "int is " << sizeof(int) << " bytes." << endl;
  cout << "int is " << sizeof n_int << " bytes." << endl;
  
  cout << "short is " << sizeof n_short << " bytes." << endl;
  cout << "long is " << sizeof n_long << " bytes." << endl;
  cout << "long long is " << sizeof n_llong << "bytes." << endl;
  cout << endl;
  
  cout << "Maximum values:" << endl;
  cout << "int: " << n_int << endl;
  cout << "short: " << n_short << endl;
  cout << "long: " << n_long << endl;
  cout << "long long: " << n_llong << endl << endl;

  cout << "Minimum int value = " << INT_MIN << endl;
  cout << "Bits per byte = " << CHAR_BIT << endl; 
  return 0;
}

C++里,新的对变量的赋值的方式

int wren(432); // alternative c++ syntax, set wren to 432
C++11初始化方式
int hamburgers = {24}; // set hamburgers to 24
int emus{7};    //set emus to 7
int rheas = {12}; //set rheas to 12
//大括号里可以不包含任何东西,这时赋零
int rocs = {};
int psychics{};
选择整型类型

​ int的长度通常被设置为,计算机处理起来效率最高的长度。如果没有非常有说服力的理由来选择其他类型,则应使用int。

​ 如果变量表示的值不可能为负,如文档的字数,则可以使用无符号类型,这样变量可以表示更大的值。

​ **如果知道变量可能表示的整数值大于16位,则使用long,即使int为32位。**这样将程序移植到16位系统时,就不会突然无法正常工作。

​ 如果存储的值超过20亿,可使用long long。

​ 如果short比int小,则使用short可以节省内存。仅当有大型整型数组时,才有必要使用short。如果节省内存很重要,则使用short而不是int,即使它们的长度是一样的。例如,将程序从int为16位的系统移植到int为32位的系统,则存储int数组的内存量将加倍,但short数组不受影响。

​ 如果只需要一个字节,可以使用char。

整型字面值
#include<iostream>
using namespace std;
int main(){
	int chest = 42;
	int waist = 0x42;
	int inseam = 042;
	cout << "Monsieur cuts a striking figure!\n";
	cout << "chest = " << chest << " 42 in decimal\n";
	cout << "waist = " << waist << " 0x42 in hex\n";
	cout << "inseam = " << inseam << " 042 in octal\n";
	return 0;
}
#include<iostream>
using namespace std;
int main(){
	int chest = 42;
	int waist = 42;
	int inseam = 42;
	cout << "Monsieur cuts a striking figure!\n";
	cout << "chest = " << chest << " 42 in decimal\n";
	cout << hex;       // 修改cout显示整数的方式
	cout << "waist = " << waist << " 0x42 in hex\n";
	cout << oct;       // manipulator for changing number base
	cout << "inseam = " << inseam << " 042 in octal\n";
	return 0;
}
C++如何确定常量的类型
cout << "Year = " << 1492 << endl;

​ 除非有用特殊的后缀来表示特定的类型,或者值太大,不能存储为int,否则c++将整型常量存储为int类型。

​ 整数后面的

  • l 或 L 后缀表示该整数为long常量,
  • u 或 U 后缀表示unsigned int常量
  • ul表示unsigned long常量
  • unsigned int 比 long更适合用来表示16位的地址
Char类型:字符和小整数

​ char 类型是另一种整型。虽然char用来处理字符,但也可以认为是比short更小的整型。

​ C++实现使用的是其主机系统的编码-----例如,IBM大型机使用EBCDIC编码。ASCII和EBCDIC都不能很好地满足国际需求,C++支持的宽字符类型可以存储更多的值,如国际Unicode字符集使用的值。使用wchar_t类型可能更合适。

​ 即使通过键盘输入的数字也被视为字符,

char ch;
cin >> ch;
//输入5并按回车,上述代码将读取字符“5”,并将其对应的字符编码(ASCII编码53)存储到变量ch中。

int n;
cin >> n;
//输入5并按回车,上述代码将读取字符“5”,并将其转换为相应的数字值5,并存储到变量n中。
Char字面值

​ 有些字符不能通过键盘输入到程序中。例如,按回车键并不能使字符串包含一个换行符;相反,程序编辑器把这种键击解释为在源代码中开始新的一行。其他一些字符也不能从键盘输入,因为c++语言赋予了它们特殊的含义。

注意,应该像处理常规字符那样处理转义序列(如\n)。也就是说,将它们作为字符常量时,应用单引号括起;将它们放在字符串中时,不要使用单引号。

通用字符名

​ 通用字符名以 \u 或者 \U 打头。\u后面是8个十六进制位,\U后面则是16个十六进制位。这些位表示的是字符的 ISO 10646 码点,为大量字符提供了数值编码。

​ 如果所用的实现支持扩展字符,则可以在标识符(如字符常量)和字符串中使用通用字符名。例如:

int k\u00F6rper;
cout << "Let them eat g\u00E2teau.\n";
signed char 和 unsigned char

​ 与int不同的是,char在默认情况下既不是没有符号,也不是有符号。是否有符号由C++实现决定,开发人员需要将这种类型与硬件属性匹配起来。

char fodo;    //may be signed, may be unsigned
unsigned char bar;   //definitely unsigned
signed char snark;   //definitely signed

​ signed char的范围通常是 -128 ~ +127, unsigned char 的范围通常是 0 ~ 255, 假设要用char变量存储200,在某些系统上可以,某些系统上不行。

​ 如果使用char变量来存储标准ASCII字符,则char有没有符号都没有关系,都可以使用char。

wchar_t

​ 8位char 可以表示基本字符集,wchar_t 可以表示扩展字符集。wchar_t 是一种整数类型,它有足够的空间,可以表示系统使用的最大扩展字符集。

​ cin 和 cout 将输入和输出看作是char流,因此不适于用来处理 wchar_t 类型。iostream头文件的最新版本提供了相似的工具——wcinwcout,用于处理 wchar_t 流。

​ 可以通过加上前缀 L 来指示宽字符常量和宽字符串。

wchar_t bob = L'P';
wcout << L"tall" << endl;

​ 在支持两字节wchar_t的系统中,上述代码把每个字符存储在一个两个字节的内存单元中。

C++11 新增的类型:char16_t 和 char32_t

char16_t,无符号,16位,使用前缀u表示char16_t 字符常量和 字符串常量,u‘C’ , u"be good";

char32_t,无符号,32位,使用前缀U表示char16_t 字符常量和 字符串常量,U’R’,U"dirty rat";

char16_t ch1 = u'q';
char32_t ch2 = U'\U00000222B';

​ 与wchar_t一样,char16_t和char32_t也都有底层类型——一种内置的整型,但底层类型可能随系统而已。

bool类型

​ 字面值true和false 都可以通过提升转换为 int 类型,true被转换为1,而 false 被转换为 0;

    ```c++

int ans = true; //ans assigned 1
int promise = false; //promise assigned 0
```

​ 另外,任何数字值或指针值都可以被隐式转换为 bool 值,任何非零值都被转换为true ,而 0 被转为false

const 限定符
const int Months = 12; 

​ 这样,便可以在程序中使用Months,而不是12了(在程序中,12可能表示一英尺有多少英寸或一打面包圈是几个,而名称 Months指出了值12表示的是什么)。

const叫限定符,因为它限定了声明的含义。

​ 如果在声明常量时没有提供值,则该常量的值将是不确定的,且无法修改。

浮点数

​ 计算机将浮点数分为两部分存储,一部分表示 , 另一部分用于对值进行 放大或缩小

​ 打个比方,对于数字34.1245 和 34124.5,它们除了小数点的位置不同外,其他都是相同的。可以把第一个数表示为0.341245 (基准值) 和 100(缩放因子),而将第二个数表示为 0.341245(基准值相同)和 10000(缩放因子更大)。缩放因子的作用是移动小数点的位置, 术语浮点因此而得名。C++内部表示浮点数的方法与此相同,只不过是基于二进制数,因此缩放因子是2的幂,不是10的幂。

浮点类型

​ C++有三种浮点类型,float 、double 、long double。

//precision problems with float
#include<iostream>
using namespace std;
int main(){
	float a = 2.34E+22f;
	float b = a + 1.0f;

	cout << "a = " << a << endl;
	cout << "b - a = " << b - a << endl;
	return 0;
}
//输出为
/*
a = 2.34e+22
b - a = 0
*/

2.34E+22的小数点左边有23位,加上1,就是在第23位加1,但float类型只能表示数字中的前6位或前7位,因此修改第23位的值不会有任何影响。

除法分支

​ 如果两个操作数都是整数,则c++将执行整数除法。这意味着小数部分将被丢弃,使得最后的结果是一个整数。

​ 如果其中有一个操作数是浮点数,则小数部分将保留,结果为浮点数。

#include<iostream>
using namespace std;
int main(){
	/*
	 cout.setf()的作用是通过设置格式标志来控制输出形式,
	 其中ios_base::fixed表示:用正常的记数方法显示浮点数(与科学计数法相对应);
	 ios_base::floatfield表示小数点后保留6位小数。
	*/
	cout.setf(ios_base::fixed, ios_base::floatfield);
	cout << "Integer division: 9/5 = " << 9 / 5 << endl;
	cout << "Floating-point division: 9.0/5.0 = " << 9.0/5.0 << endl;
	cout << "double constants: 1e7/9.0 = " << 1e7 / 9.0 << endl;
	cout << "float constants: 1e7f/9.0f = " << 1e7f / 9.0f << endl;
	return 0;
}
/*
Integer division: 9/5 = 1
Floating-point division: 9.0/5.0 = 1.800000
double constants: 1e7/9.0 = 1111111.111111
float constants: 1e7f/9.0f = 1111111.125000
*/
类型转换

​ 将两个short值相加涉及到的硬件编译指令可能会与将两个long值相加不同。

  • 将一种算术类型的值赋给另一种算数类型的变量时,C++将对值进行转换;

  • 表达式中包含不同的类型时,C++将对值进行转换;

  • 将参数传递给函数时,C++将对值进行转换。

    ​ 将一个值赋给取值范围更大的类型通常不会导致什么问题。例如,将short值赋给long变量并不会改变这个值,只是占用的字节更多了而已。 **然而,将一个很大的long值(如2111222333)赋给float变量将降低精度。**因为float只有6位有效数字,因此这个值将被四舍五入为2.11122E9。

    ​ 有些转换是安全的,有些是会带来麻烦的。

    ​ 浮点值转换为整型会将数字截短(除掉小数部分)。其次float对于int可能太大了,这种情况下的结果与硬件有关。

以{}方式初始化时进行的转换

​ 这种初始化方式被称为 列表初始化,这种初始化常用于给 复杂的数据类型 提供值列表。

​ 它对类型的转换要求更为严格。不允许缩窄类型,不允许将浮点类型转换为整型。

​ 在不同的整型之间转换或将整型转换为浮点型可能被允许,例如可将long变量初始化为int值,因为long总是至少与int一样长;相反方向的转换可能也被允许,只要int变量能够存储赋给它的long常量。

char c1 {31325};  //narrowing , now allowed;
char c2 = {66};   //allowed because char can hold 66
int x = 66;
char c3 = {x};   //not allowd , x is not constant 
/*
	初始化c3时,您知道x的值为66,但是编译器看来x是一个变量,其值可能很大。编译器不会跟踪下述阶段可能发生的情况:从x被初始化到它被用来初始化c3。
*/
表达式中的转换

​ 自动转换。在计算表达式时,c++将bool、char、unsigned char、signed char和short值转为int。

short chickens = 20;
short ducks = 35;
short fowl = chickens + ducks;
/*
	C++程序取得chickens和 ducks的值,并将它们转为int,最后将结果转为 fowl。
*/

​ 如果short比int短,则unsigned short类型将被转换为int;如果长度相同,则unsigned short类型将被转换为unsigned int,这种规则确保unsigned short进行提升时不会损失数据。

​ C++可以通过强制类型转换机制显式的进行类型转换。强制类型转换不会改变该变量本身,而是创建一个新的、指定类型的值。

​ 强制类型转换的通用格式如下:

(typename) value

typename (value)

​ 第一种格式来自C语言,第二种是纯粹的C++。新格式的想法是, 要让强制类型转换就像是函数调用。

​ C++还引入了4个强制类型转换运算符,对它们的使用更为严格。

​ **static_cast (value) ** // convert value to typename type

C++11中的auto声明

​ 在初始化声明中,如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同;

 auto n = 100;  //n is int
 auto x = 1.5;  //x is double
 auto y = 1.3e12L; //y is long double

​ 处理复杂类型,如STL中的类型时,自动推断类型的价值才能显示出来。例如对于,C++98代码:

std::vector<double> scores;
std::vector<double>:: iterator pv = scores.begin();

C++11允许重写为

std::vector<double> scores;
auto pv = scores.begin();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值