目录
第一章、c++快速入门
1、注释对不能嵌套!!!若想注释掉某行代码用单行注释!!
2、定义在for循环中的变量在退出for循环后不能再访问。如下var
int m;
for(int var=0;var<10;var++)
{
m+=var;
}
printf("%d\n",m); //m可以访问,var不可访问
3、windows系统下通过键入Ctrl+z来输入文件结束符。例如下:
int var,sum;
while(std::cin>>var)
{
sum++;
}
输入Ctrl+z时程序会终止循环。
重点:类的简介
1、类可以是系统自带的,比如iostream,也可以自定义。引用方式不同,如下
#include <iostream>
#include "Sales_item" //自定义类用双引号
2、每个类定义一种类型,类里面还有对象和成员函数(也叫类方法)等。如下:
int main()
{
Sales_item item1,item2;
std::cin>>item1>>item2;
if(item1.same_isbn(item2)) //以.的方式引用成员函数
{
std::cout<<item1+item2<<std::endl;
//两个对象可以相加,具体要看Sales_item头文件里让相加做什么
}
return 0;
}
第二章
1、基本内置类型
1、wchar_t类型用于扩展字符集,如汉字和日语等。
2、存储方式:通常将8位的块作为一个字节。32位或4个字节作为一个字(word)。
3、带符号类型可以表示正数、负数、0。 无符号类型只能表示正数和0。
4、一个使用一位符号位的表示方式为8位的signed整型取值是从-128到127。
5、c++中,把负值赋给unsigned对象是完全合法的,其结果是该负数对该类型的取值个数求模后的值。(如-1赋给8位unsigned char结果是255,即-1对256求模)
6、long类型运行时代价远远高于用int类型进行同样计算的代价。
7、float类型中隐式的精度损失不能忽视,但double计算的代价相对于float可以忽略。
2、字面值常量
只有内置类型存在字面值,没有类类型的字面值。因此也没有任何标准库类型的字面值。
1、整型字面值规则
1、以0开头的字面值整数常量表示八进制,以0x或0X开头的表示十六进制。
2、在数值后面加L指定常量为long类型。在数值后面加U或u定义unsigned类型。同时加L和U得到unsigned long类型的字面值常量(注意后缀不能有空格!!)。没有short型的字面值常量。
128u //unsigned
1L //long
1024UL //unsigned long
8LU //unsigned long (U和L谁在前都可)
2、浮点字面值规则
默认的浮点字面值常量为double类型。在数值后加上F或f表示单精度。加上L表示扩展精度。
3.14159F //每组表示的数值相同
3.14159E0f
.001f
1E-3F
12.345L
1.2345E1L
0.
0e0
3、布尔字面值
true和false
bool test=false;
4、字符字面值
在字符字面值前面加L能得到wchar_t类型的宽字符字面值。
'a'
L'a'
5、非打印字符的转义序列
可以用八进制和十六进制转义字符来定义任何字符
6、字符串字面值
1、“A”是包含字母A和空字符‘\0’两个字符的字符串。
2、宽字符字面值是一串常量宽字符,以一个宽空字符结束。
L"a wide string literal"
3、字符串字面值的连接
法(1)、两个相邻的仅由空格、制表符或换行符分开的字符串字面值(或宽字符串字面值),可连接成一个新字符串字面值。这样可以多行书写长字符串字面值。
std::cout<<"apple banana " //末尾留空格
/*后继行行首随便空格或者制表符,不算入字符串内部*/ "pear grape "
"orange strawberry"
<<std::endl;
输出:apple banana pear grape orange strawberry
法(2)、 多行字面值也可以处理长字符串。
在一行的末尾加一个反斜线符号可将此行和下一行当做同一行处理。
std::cou\
t<<"hello"<<st\
d::endl;
相当于
std::cout<<"hello"<<std::endl;
std::cout<<"apple banana \
pear grape \
orange strawberry"
<<std::endl;
输出:apple banana pear grape orange strawberry
注意反斜线符号必须是该行的尾字符,不允许其后面有注释或空格!!!
采用\处理多行字面值时,后继行行首的任何空格和制表符都是字符串字面值的一部分。因此,长字符串字面值的后继行不能有缩进(除非上一行行尾还没缩进完)。
3、变量
对象就是内存中具有类型的区域。
1、变量标识符
关键字不能用作变量的标识符。如下:
下面这张仅做了解。
注:以下标识符是可以的
Float
_
2、定义和初始化对象
对象初始化可以用复制初始化(=)或直接初始化(括号)
int var=1024;
int var(1024);
直接初始化的语法更灵活且效率更高。
注:初始化不是赋值!!初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。
对内置类型来说,复制初始化和直接初始化几乎没有差别。
对类类型的对象来说,有些初始化仅能用直接初始化完成。定义如何进行初始化的成员函数称为构造函数。
#include <string>
std::string titleA="c++ primer,4th ed.";
std::string titleB("c++ primer,4th ed.");
std::string all_nines(10,'9');
//all_nines="9999999999"
//这种初始化方式也是直接初始化,有多个初始化式(初始化值可变)时不能用复制初始化。
可以用同一个定义中前面已定义的值初始化后面的变量。
double salary=9999.99,wage(salary+0.01);
3、变量初始化规则
1、内置类型变量的初始化
在函数体外定义的变量都初始化成0,在函数体内定义的内置类型变量不进行自动初始化。
2、类类型变量的初始化
如果类具有默认构造函数,那么就可以在定义该类的变量时不用显示地初始化变量。
#include <iostream>
#include <string>
int main()
{
std::string empty; //定义了一个名为empty的字符串变量,并且不进行初始化
std::cout<<empty<<std::endl; //输出" "(空字符),string类型默认初始化为空
}
有些类类型没有默认构造函数,那么每个定义都必须提供显示的初始化式,没有初始值根本不可能定义这种类型的变量。
4、声明和定义
1、定义:用于为变量分配存储空间,指定初始值。
2、声明:用于向程序表明变量的类型和名字。不分配存储空间!!
定义也是声明!!
3、可以通过extern关键字声明变量而不定义它。
extern int i; //声明但不定义
int i; //定义
注:一个变量只能定义一次!!但可以声明多次!!
4、当extern声明位于函数外部时,才可以含有初始化式。如果声明有初始化式,那么该声明也是定义。
extern double pi=3.14159; //声明的同时定义
5、任何在多个文件中使用的变量都需要有与定义分离的声明。
5、名字的作用域
1、全局作用域:定义在所有函数外部的名字
2、局部作用域:函数内的名字
3、语句作用域:定义在如for语句内
int add=0; //全局作用域
int main()
{
int sum=0; //局部作用域
for(int i=0;i<10;i++) //语句作用域
{
sum++;
}
}
作用范围:全局>局部>语句
若小作用域中某变量的名字和大作用域中某变量名字相同,则当运行到小作用域时,会屏蔽大作用域中对该变量的赋值或操作。
最好在使用变量时定义它,不要全都定义在开头。
4、const限定符
常量在定义之后不能被修改,所以定义时必须初始化。
在全局作用域声明的const变量是定义该对象的文件的局部变量。此变量只存在于那个文件中,不能被其他文件访问。
通过指定const变量为extern,就可以在整个程序中访问const对象。
//file_1.cpp
extern const int buf=fcn(); //文件1中定义
//file_2.cpp
extern const int buf; //文件2中声明并使用
for(int index=0;index!=buf;++index)
{
//……
}
非const变量默认为extern。要使const变量能够在其他文件中访问,必须显示地指定它为extern。
int cnt=0;
const int sz=cnt; //合法
5、引用
引用是对象的另一个名字。主要作为函数的形参。
引用必须用与该引用同类型的对象初始化。
int ival=1024;
int &refval=ival; //合法
int &refval2; //不合法,引用必须初始化
int &refval3=10; //不合法,引用的右值必须是对象
作用在引用上的所有操作事实上都作用在该引用绑定的对象上。
当引用初始化后,只要该引用存在,它就保持绑定到初始化时指向的对象。不可能将引用绑定到另一个对象。
const引用:指向const对象的引用
const int ival=1024;
const int &refval=ival;
int &ref2=ival; //不合法,不是const引用
非const引用只能绑定到与该引用同类型的对象。
const引用可以绑定到不同但相关的类型的对象或绑定到右值。
double dval=3.14;
const int &ri=dval;
//编译器会转化为以下代码
int temp=dval;
const int &ri=temp;
6、typedef 名字
typedef double wages;
typedef wages salary;
typedef int exam_score;
7、枚举
1、定义和默认赋值
enum Forms {shape=1,sphere,cylinder,polygon}; //默认逐个+1
//sphere=2, cylinder=3, polygon=4
enum Points {point2d = 2, point2w, point3d = 3, point3w };//在前一个基础上+1
//point2w=3, point3w=4
2、枚举类型的对象的初始化或赋值,只能通过其枚举成员或同一枚举类型的其他对象来进行。
Points pt3d = point3d; //√,point3d是Points的枚举成员
Points pt2w = 3; //×
pt2w = polygon; //×
pt2w = pt3d; //√,pt3d和pt2w都是同一个枚举类型的枚举成员
8、类类型
1、从操作接口设计类。每个类都定义了一个接口和一个实现。
定义类时,通常先定义该类的接口,即该类所提供的操作。通过这些操作,可以决定该类完成 其功能所需要的数据和函数。
2、一般不能把类成员的初始化作为其定义的一部分。定义数据成员时,只能指定该数据成员的名字和类型。
3、c++中定义类类型除了关键字class以外,还支持另一个关键字struct(从C语言继承过来的)
用class和struct关键字定义类的唯一差别在于默认访问级别。默认情况下,struct的成员为public,而class的成员为private
9、编写自己的头文件
为了允许把程序分成独立的逻辑块,c++支持分别编译
1、头文件一般包括类的定义、extern变量的声明和函数的声明。
2、正确使用头文件的好处:(1)保证所有文件使用给定实体的同一声明
(2)当声明需要修改时,只有头文件需要更新
3、头文件用于声明而不是定义
定义只可以出现一次,声明可以出现多次
extern int ival = 10; //虽然有 extern,但有初始化式,是定义
double fic; //虽然没有初始化式,但也没有extern,所以也是定义
同一个程序中有两个以上文件含有上述任意一个定义都会导致多重定义链接错误。
又因为头文件包含在多个源文件中,所以头文件不应该含有变量或函数的定义。
对于上述规定,有三个例外。头文件可以定义类、值在编译时就知道的const对象和inline函数
(const变量和它的初始化式必须是每个文件都可见的。而要使初始化式可见,一般都把这样的const变量定义在头文件中)
但如果const变量不是用常量表达式初始化,那么它就不应该在头文件中定义。应该在一个源文件中定义并初始化,并在头文件里为它加上extern声明。
4、预处理器
(1)头文件中有可能会引用其他头文件,所以源文件对于某个头文件可能会直接引用一次又间接引用一次。
因此设计头文件时应使其可以多次包含在同一源文件中。保证多次包含同一头文件不会引起该头文件定义的类和对象被多次定义。
头文件保护符可以避免在已经见到头文件的情况下重新处理该头文件的内容。
(2)避免多重包含:
为避免名字冲突,预处理器变量通常用大写字母表示
预处理器有两种状态:已定义或未定义。
#define 表示定义预处理器变量 #ifndef 表示检测指定的预处理器变量是否未定义
如果预处理器变量未定义,那么跟在其后的所有指示都被处理,直到出现#endif
例:
#ifndef SALES
#define SALES
//Defination of class
#endif
若SALES预处理器变量未定义,#ifndef测试成功,跟在#ifndef后面的所有行都被执行,直到#endif
若SALES预处理器变量已定义,#ifndef测试为假,#ifndef到#endif的部分都会被忽略
(3)自定义头文件
#include <xxx> 标准头文件 #include “xxx” 自定义头文件