220223_C++_Primer_Plus_自学笔记_3_处理数据
目录
变量命名
- 名称中只能使用字母字符、数字和下划线。
- 名称的第一个字符不能是数字。
- 区分大写字符与小写字符。
- 不能将C++关键字用作名称。
- 以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。(???)
- C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制。
变量初始化
变量初始化有很多方法:
#include <iostream>
using namespace std;
int main ()
{
int a = 1;
int b;
b = 2;
int c{3};
int d(4);
int e={5};
int f; // 没有初始化。
int g={}; // {}的初始化没有数值,默认赋为0。
cout<<"a"<<a<<endl;
cout<<"b"<<b<<endl;
cout<<"c"<<c<<endl;
cout<<"d"<<d<<endl;
cout<<"e"<<e<<endl;
cout<<"f"<<f<<endl;
cout<<"g"<<g<<endl;
return 0;
}
初始化时:如果第一位为1~9,则基数为10(十进制);
如果第一位是0,第二位为1~7,则基数为8(八进制);
如果前两位为0x或0X,则基数为16(十六进制)。
cout默认会用十进制输出。可用cout的其他控制符控制输出:
cout << "Monsieur cuts a striking figure!" << endl;
cout << "chest = " << chest << " (decimal for 42)" << endl;
cout << hex; // manipulator for changing number base
cout << "waist = " << waist << " (hexadecimal for 42)" << endl;
cout << oct; // manipulator for changing number base
cout << "inseam = " << inseam << " (octal for 42)" << endl;
数据类型
不同数据类型占用内存大小不同,表达的数字类型、数字范围不同。
C++提供了一种灵活的标准,它确保了最小长度(从C语言借鉴而来),如下所示:
- 整型short至少16位;
- int至少与short一样长;
- long至少32位,且至少与int一样长;
- long long至少64位,且至少与long一样长。
字节(byte)通常指的是8位的内存单元。
从这个意义上说,字节指的就是描述计算机内存量的度量单位,在美国,基本字符集通常是ASCII和EBCDIC字符集,它们都可以用8
位来容纳,所以在使用这两种字符集的系统中,C++字节通常包含8位。然而,国际编程可能需要使用更大的字符集,如Unicode,因此有些实现可能使用16位甚至32位的字节。有些人使用术语八位组(octet)表示8位字节。当前很多系统都使用最小长度,即short为16位,long为32位。这仍为int提供了多种选择,其宽度可以是16位、24位或32位,同时又符合标准;甚至可以是64位,因为long和long long至少长64位。通常,在老式IBM PC的实现中,int的宽度为16位(与short相同),而在WindowsXP、Windows Vista、Windows 7、Macintosh OS X、VAX和很多其他微型计算机的实现中,为32位(与long相同)。
总而言之,因为这些原因,C++中,在不同系统中,同一数据类型所占用的空间是不同的。比如int就不低于16位,不超过32位。
可以通过 sizeof函数 以及 climits文件 查看数据所占内存大小:
int n_int = INT_MAX; // initialize n_it to max int value
short n_short = SHRT_MAX; // symbols defined in climits file
long n_long = LONG_MAX;
long long n_llong = LLONG_MAX;
// sizeof operator yields size of type or of variable
cout << "int is " << sizeof (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;
CHAR_BIT char的位数 |
---|
CHAR_MAX char的最大值 |
CHAR_MIN char的最小值 |
SCHAR_MAX signed char的最大值 |
SCHAR_MIN signed char的最小值 |
UCHAR_MAX unsigned char的最大值 |
SHRT_MAX short的最大值 |
SHRT_MIN short的最小值 |
USHRT_MAX unsigned short的最大值 |
INT_MAX int的最大值 |
INT_MIN int的最小值 |
UNIT_MAX unsigned int的最大值 |
LONG_MAX long的最大值 |
LONG_MIN long的最小值 |
ULONG_MAX unsigned long的最大值 |
LLONG_MAX long long的最大值 |
LLONG_MIN long long的最小值 |
ULLONG_MAX unsigned long long的最大值 |
整型 int
包含short,int , long int,long long int四种类型。表示有符号的整数.
无符号整型 unsigned int
在整型前增加关键字 unsigned即可。
例如,short的显示范围是-32768~32767;unsigned short的显示范围为0~65536。超出范围将会导致“溢出”。
字符型char
单引号 ' ' 引起。
计算机中,常常使用ASCII编码。计算及存储的是字符编码。
#include <iostream>
using namespace std;
int main ()
{
int a = 67;
cout.put(a);
char b = 'b';
cout<<endl<<int (b)<<endl;
return 0;
}
//输出C98
cout.put()
是 cout
的成员函数,用于输出字符。
转义字符(Escape Character)是指在ASCII码和Unicode等字符集中的无法被键盘录入的字符、被当作特殊用途而需要转换回它原来的意义的字符。而转义字符的转义是指字符已经被转换了意义。
对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,即不能在显示器上显示,甚至无法从键盘输入;部分控制字符在编辑语言中还被定义为特殊用途。因此只能用转义字符的形式来表示它们。不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以针对常用的控制字符,各类编程语言对转义字符又定义了简写方式。也可用用\x
开头的十六进制数来表示转义。如换行符\n
也可以写作\x0a
。
C++实现支持一个基本的源字符集,即可用来编写源代码的字符集。它由标准美国键盘上的字符(大写和小写)和数字、C语言中使用
的符号(如{和=}以及其他一些字符(如换行符和空格)组成通用字符名的用法类似于转义序列。通用字符名可以以\u或\U打头。\u后面是8个十六进制位,\U后面则是16个十六进制位。这些位表示的是字符的ISO 10646码点。
signed char / unsigned char
默认char既不是没有符号,又不是有符号的。如果有需要的话,需要用户定义。有符号的-128~127;无符号的 0~255。
宽字符型 wchar_t / C++11中的新类型char16_t /char32_t
在有些字符集无法用一个8位的字节表示时,需要对char进行拓宽。
bool型
布尔变量的值可以是 true 和 false。
true可以被转化为int的1,false可以被转化为int的0。
任何非零值可以被转化为true,0可以转化为false。
浮点数 float / double / long double
浮点型数字能表示带小数的数字。计算机将浮点数分为两部分:一部分表示数值,一部分表示缩放。
浮点数有两种书写方式,第一种是常用的小数点表示法。
第二种则是将数值与缩放结合。
因此,任何浮点数都可以表示为:浮点数 = 尾数 * 2 ^阶码
浮点型数据的范围 - QuentinYo - 博客园 (cnblogs.com)
在程序中书写浮点常量的时候,程序将把它存储为哪种浮点类型呢?
在默认情况下,像8.24和2.4E8这样的浮点常量都属于double类型。
如果希望常量为float类型,请使用f或F后缀。
对于long double类型,可使用l或L后缀(由于l看起来像数字1,因此L是更好的选择)。
与整数相比,浮点数有两大优点。首先,它们可以表示整数之间的值。
其次,由于有缩放因子,它们可以表示的范围大得多。
另一方面,浮点运算的速度通常比整数运算慢,且精度将降低。
(学完《数值分析》就了解到,可能看似很小的误差在经过繁复的运算之后会演化成巨大的误差导致数值没法用。)
// arith.cpp -- some C++ arithmetic
#include <iostream>
int main()
{
using namespace std;
float hats, heads;
cout.setf(ios_base::fixed, ios_base::floatfield); // fixed-point
cout << "Enter a number: ";
cin >> hats;
cout << "Enter another number: ";
cin >> heads;
cout << "hats = " << hats << "; heads = " << heads << endl;
cout << "hats + heads = " << hats + heads << endl;
// Enter a number: Enter another number: hats = 50.250000; heads = 11.170000
//hats + heads = 61.419998
return 0;
}
这个例子可以看出float会造成误差。float一定能保证6位有效数字。将 61.419998舍入到6位有效数字四舍五入就是精确解。
const 限定符
例如 const int Caaa = 12;
这样,程序中变量Caaa就被定为常值,它的值就一直是12,不再允许aaa被修改。
一般可以将常量变量首字母大写。
在使用const限定符时候,一定要对常量进行初始化赋值。
一般认为const 比 #define更好。
const与#define的区别、优点 - 云+社区 - 腾讯云 (tencent.com)
编译器处理方式不同
define宏是在预处理阶段展开。
补充:预处理器根据以#开头的命令,修改原始的程序。比如我们常见的#include <stdio.h>命令告诉处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中。咱们的#define也是,仅仅是单纯的文本替换。
const常量是编译运行阶段使用。
(在接触#if、#undef这类预处理指令前,大部分都都接触过#define、#include等预处理命令,通俗来讲预处理命令的作用就是在编译和链接之前,对源文件进行一些文本方面的操作,比如文本替换、文件包含、删除部分代码等,这个过程叫做预处理。在编译之前对源文件进行简单加工(#define是一种宏定义命令,是预处理命令的一种)
类型和安全检查不同
define宏没有数据类型,不做任何类型检查,仅仅是展开。
const常量有具体的数据类型,编译阶段会执行类型检查。
存储方式不同
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(可以是堆中也可以是栈中)。
const 可以节省空间,避免不必要的内存分配。
算术运算符
对于 / 的除法,分子分母都是int数据得到的结果也会是int数据。
对于 % 的取余,分子分母都必需是整型。
不同运算的优先级:[C++运算符优先级表中文版]_C语言中文网 (biancheng.net)
数据类型转换
C++中的数据经常会发生类型的转化,详细介绍几种情况如下。
1.初始化和赋值进行的转换
一般将小范围数据转换为大范围数据,将int转化为float不会出现问题。
反之,将会破坏精度。
2.以{ }方式初始化时进行的转换(C++11)
3.表达式中的转换
不同数据类型进行算术运算,较小的类型会被转化为较大的类型。
4.传递参数时的转换
函数功能在传递数据时,常常由C++的函数原型控制。
5.强制类型转换
例如对于float数a: int b = (int) a
,不会影响a的本身数值,而是将这个数值取int赋值给b。
这是C语言的强制转换类型。C++另有static_cast<>
,这比传统的强制类型转换更严格。