面向对象编程的本质是设计并扩展自己的数据类型。
设计自己的数据类型就是让类型与数据匹配。
3.1简单变量
3.1.1变量名
3.1.2整型
3.1.3整型short、int、long和long long
sizeof运算符可以用来检查类型的长度,sizeof运算符返回类型或者变量的长度,单位为字节。
字节的含义依赖于实现,在一个系统中,两字节的int可能是16位,而在另一个系统中可能是32位。其次,头文件climits中包含了关于整型限制的信息,eg:INT_MAX为int的最大取值,CHAR_BIT为字节的位数。
下面是64位的qindows 7系统跑出来的结果
// limits.cpp -- some integer limits
#include <iostream>
#include <climits> // use limits.h for older systems
int main()
{
using namespace std;
int n_int = INT_MAX; // initialize n_int 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;
// cin.get();
return 0;
}
1.运算符sizeof和头文件limits
可以对类型名或者变量名使用sizeof运算符;
头文件climits定义了符号常量,来表示类型的限制
符号常量——预处理器方式
climits文件中包含与下面类似的语句行
#define INT_MAX 32767
在C++编译过过程中,首先将源代码传递给预处理器,在这里,#define和#include一样,是一个预处理器编译指令,该指令告诉预处理器:在程序中查找INT_MAX,并将所有的INT_MAX都替换成32767,因此,#define编译指令的工作方式与文本编辑器或字处理器的全局搜索并替换命令相似。需要指出的是,有些头文件,尤其是被设计成可用于C和C++中的头文件,必须使用#define
C++有一种更好的创建符号常量的方法,使用关键字const
2.初始化
3.C++11初始化方式
除了=,还有大括号初始化器的使用
3.1.4无符号类型
要创建无符号版本的基本整型,只需要使用关键字unsigned来修改声明即可
主要关注下面的一张图片,C++符号整型超越限制的时候,出如何?
3.1.5选择整型类型
具体的eg如下:
3.1.6整型字面值
C++使用前一(两)位来标识数字常量的基数;
第一位是1-9,则基数是10(十进制),eg:93是以10为基数;
第一位是0,第二位是1-7,基数是8(八进制),eg:042=34(十进制);
前两位是0x或0X,则基数为16(十六进制),eg:0x42为十六进制数=66(十进制);
eg:cout以十进制格式显示整数
// hexoct1.cpp -- shows hex and octal literals
#include <iostream>
#include<stdlib.h>
int main()
{
using namespace std;
int chest = 42; // decimal integer literal
int waist = 0x42; // hexadecimal integer literal
int inseam = 042; // octal integer literal
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";
// cin.get();
system("pause");
return 0;
}
eg:cout保持原进制数输出
主要是控制符dec、hex、oct的使用
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
using namespace std;
int chest = 42;
int waist = 42;
int inseam = 42;
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;
// cin.get();
system("pause");
return 0;
}
3.1.7 C++确定常量的类型
例如,整型常量默认存储为int;
首先看后缀,接下来考察长度。
3.1.8 char类型:字符和小整数
char类型是另外一种整型,它足够长,能够表示目标计算机系统中的所有基本符号——所有的字母、数字、标点符号等等。字符集中的字符是用数值编码(ASCII码)表示的,eg:字符A的编码是65,字母M的额编码是77
C++对字符用单引号,对字符串使用双引号
下面来看一个例子:
// morechar.cpp -- the char type and int type contrasted
#include <iostream>
int main()
{
using namespace std;
char ch = 'M'; // assign ASCII code for M to ch
int i = ch; // store same code in an int
cout << "The ASCII code for " << ch << " is " << i << endl;
cout << "Add one to the character code:" << endl;
ch = ch + 1; // change character code in ch
i = ch; // save new character code in i
cout << "The ASCII code for " << ch << " is " << i << endl;
// using the cout.put() member function to display a char
cout << "Displaying char ch using cout.put(ch): ";
cout.put(ch);
// using cout.put() to display a char constant
cout.put('!');
cout << endl << "Done" << endl;
// cin.get();
return 0;
}
在上述的程序当中,‘M’表示字符M的数值编码(ASCII),因此将char变量ch初始化为‘M’,把ch设置为77。然后,程序将同样的值赋值给int变量i,这样ch和i都是77。最后,cout把ch显示为M,把i显示为77.
由于ch实际上是一个整数,因此可以对他使用整数操作。
cout.put()成员函数可以显示字符,可以代替<<运算符。要通过对象(eg:cout)使用成员函数,必须用句点将对象名和函数名(put())连接起来使用,句点称之为成员运算符。
一些常见的ASCII的对应情况,如下:
C++转义序列
由于有些字符是不能直接通过键盘输入到程序中,C++语言赋予了它们特殊的含义。
将他们作为字符常量的时候,应用单引号括起来,将他们放在字符串中时,不要使用单引号
eg如下:
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
using namespace std;
using namespace std;
cout << "\aOperation \"HyperHype\" is now activated!\n";
cout << "Enter your agent code:________\b\b\b\b\b\b\b\b";
long code;
cin >> code;
cout << "\aYou entered " << code << "...\n";
cout << "\aCode verified! Proceed with Plan Z3!\n";
// cin.get();
// cin.get();
cout<<sizeof('ji\n')<<endl;
cout<<sizeof("ji\n")<<endl;
system("pause");
return 0;
}
说明:程序使用退格字符将光标退到第一个下划线处。
通用字符名
eg如下:
输出:
说明:
3.2 const限定符
C++处理符号常量的方法就是,用const关键字来修改变量申明和初始化。
关键字const叫做限定符,限定了申明的含义,编译器不孕寻再修改该常量的值。
eg:
命名规则:
C语言中的#define与C++中的const的区别
首先,const比#define好,原因如下:
1)const能够明确指定类型
2)C++的作用域规则将定义限制在特定的函数或文件中
3)const可以用于更加复杂的类型
3.3浮点数
能够表示带小数部分的数字
3.3.1书写浮点数
1)使用常用的标准小数点表示法
2)E表示法
eg:
3.3.2浮点类型
C++提供了3种浮点类型:float,double,long double,这些类型是按它们可以表示的有效数位和允许的指数最小范围来描述的,
通常,float为32位,double为64位,long double为80,96,或128位。
eg:
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield); // fixed-point
float tub = 10.0 / 3.0; // good to about 6 places
double mint = 10.0 / 3.0; // good to about 15 places
const float million = 1.0e6;
cout << "tub = " << tub;
cout << ", a million tubs = " << million * tub;
cout << ",\nand ten million tubs = ";
cout << 10 * million * tub << endl;
cout << "mint = " << mint << " and a million mints = ";
cout << million * mint << endl;
// cin.get();
system("pause");
return 0;
}
通常cout会删除结尾的0,eg将3333333.250000->3333333.25,调用cout.setf()将覆盖这种行为。
这里,为啥float的精度比double低?
tub和mint都被初始化为:10.0/3.0=3.333333333333333333333…由于cout打印6位小数,因此,tub和mint都是精确的。而将每个数乘以一百万以后,系统确保了float至少有6位是有效位,确保double至少有13位是有效位,故可知是精度限制
3.3.3浮点常量
3.3.4浮点数的优缺点
相较于整数,浮点数的优点在于:
1)它们可以表示整数之间的值
2)由于有缩放因子,它们可以表示范围大得多的数
缺点:浮点运算的速度比整数慢,且精度将降低
eg:
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
using namespace std;
//cout.setf(ios_base::fixed, ios_base::floatfield); // fixed-point
float a = 2.34E+22f;
float b = a + 1.0f;
cout << "a = " << a << endl;
cout << "b - a = " << b - a << endl;
// cin.get();
system("pause");
return 0;
}
按照该程序字面的理解,结果应该为1。但是却输出了上述的结果,这是为啥呢?
3.4 C++算数运算符
下面是五种基本的C++算术运算符
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
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;
cout << "hats - heads = " << hats - heads << endl;
cout << "hats * heads = " << hats * heads << endl;
cout << "hats / heads = " << hats / heads << endl;
system("pause");
return 0;
}
对于上述,画箭头的部分,说明如下:
3.4.1 运算符优先级和结合性
1)*,/和%优先级相同;
2)当两个优先级相同的运算符被同时作用于一个操作数的时候,结合性应该按照从左到右的方式,eg:
上面的答案应该是150
3)一个特别的例子如下:(知道即可)
3.4.2除法分支
1)如果两个操作数都是整数,则结果会将小数部分丢弃,使得最后的结果是一个整数
2)如果其中有一个或两个操作数都是浮点数,则小数部分保留,结果为浮点数。
eg:
// hexoct2.cpp -- display values in hex and octal
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "Integer division: 9/5 = " << 9 / 5 << endl;
cout << "Floating-point division: 9.0/5.0 = ";
cout << 9.0 / 5.0 << endl;
cout << "Mixed division: 9.0/5 = " << 9.0 / 5 << endl;
cout << "double constants: 1e7/9.0 = ";
cout << 1.e7 / 9.0 << endl;
cout << "float constants: 1e7f/9.0f = ";
cout << 1.e7f / 9.0f << endl;
system("pause");
return 0;
}
3.4.3 求模运算符
适用于解决将一个量分成不同的整数单元的问题
eg:
3.4.4 类型转换
1)初始化和赋值进行转换
eg:
2)C++11以{}方式初始化时进行的转换
在不同的整型之间转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量能够正确地存储赋给它的值。
C++11将使用大括号的初始化称为列表初始化,它对类型转换的要求更严格。列表初始化不允许缩窄(narrowing),即变量的类型可能无法表示赋给它的值。
eg:
3)表达式中的转换