初学C++,记下一些自己觉得重要的地方,留着以后查阅复习。文中大多参考自:C++ primer plus
1、 main函数
main()函数中如果编译器到达了函数末尾没有遇到返回语句,则认为main()函数以:return 0;语句结尾,这条隐含的返回语句只适用于main()函数,不适用于其他函数。
2、 cin和cout
使用cin和cout进行输入和输出的程序必须包含iostream头文件。
3、 endl
endl是一个特殊的C++符号,表示重起一行,cout << endl;与”\n”效果类似。与之不同之处在于endl确保程序继续运行前刷新输出,而\n不提供这种保证。
4、 usingnamespace std;语句使用方式:
(1) 将usingnamespace std;放在函数定义之前,让文件中所有的函数都能使用名称空间std中的所有元素;
(2) 将usingnamespace std;放在特定的函数定义中,让该函数能够使用名称空间std中的所有元素。
(3) 在特定的函数中使用类似using std::cout;这样的编译指令,而不是using namespacestd;让该函数能够使用特定的元素,如cout。
(4) 完全不适用编译指令using,而在需要使用名称空间std中的元素时,使用前缀std::,如std::cout << “I’m using cout and endl from the std namespace” << std::endl;
5、 整型字面值
对整型有三种不同的字面书写形式:(1)基数为10计数方式。第一位为1~9,如93;(2)基数为8计数方式。第一位为0,第二位为1~7,如042,相当于10进制34;(3)基数为16计数方式。第一位为0,第二位为0x或0X,如0x42,相当于十进制66,0xF为15。
6、const常量定义符
const与java中final相似。定义变量时加上const修饰,该变量变成了常量不允许修改。
7、\0的含义
\0表示字符数组的结束符,如char name2[15] = “C++owboy”;使用sizeof(name2)得到长度为15个字节,使用strlen(name2)得到实际的字符串长度为8。如果将name[3]=’\0’,则输出name2时为C++,后面的字符全被忽略。
8、字符串输入
#include<iostream>
int main()
{
using namespace std;
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << “Enter your name:\n”;
cin >> name;
cout << “Enter your favorite dessert:\n”;
cin >> dessert;
cout << “I have some delicious ” << dessert;
cout << “for you, ” << name << “.\n”;
}
输出结果:
Enter your name:
Alistair Dreeb
Enter your favoritedessert:
I have some delicious Dreeb for you,Alistair.
从结果可以看出当还没对“Enter your favoritedessert:”做出反应,程序就执行了下一行了。原因是cin使用空白(空格、制表符和换行)来确定字符串的结束位置,这意味着cin在获取字符串数组输入时只读取一个单词。读取单词后,cin将字符串放在数组中,并自动在结尾添加\0字符。在该例子中,cin把Alistair作为第一个字符串,并将他放入name数组中,同时把Dreeb保留在输入队列中。当cin在输入队列中搜索用户喜欢的甜点时,它发现了Dreeb,因此cin读取出Dreeb,并将他放在了dessert数组中。
9、每次读取一行字符串输入
为解决读取完整的字符串,iostream中的类如cin提供了面向行的类成员函数:getline()和get()方法,这两个函数都是读取一行的输入,直到换行符为止。不同之处在于,getline()方法会丢弃换行符替换成了\0空字符,而get()方法保留了换行符。用法:cin.getline(字符数组,长度);如getline(name, 20);
get()方法与getline()方法类似,但比他稍复杂一些,get()方法读取一行字符串时,它并不读取并丢弃换行符,而是将其留在输入队列中,下一次再执行get()方法时则获取到的字符串就为换行符。如下一列子:
#include<iostream>
int main()
{
using namespace std;
cout << “Whatyear was your house built?\n”;
int year;
cin >> year;
cout << “What isits street address?\n”;
char address[80];
cin.getline(address,80);
cout << “Yearbuilt: ” << year << endl;
cout << “Address:” << address << endl;
cout << “Done!\n”;
return 0;
}
输出结果:
What year was yourhouse built?
1966
What is its streetaddress?
Year built:1966
Address
Done!
用户根本没有输入地址的机会,因为在输入年份时cin将换行符保留在了输入队列中,当要求输入地址时,则将输入队列中的换行符给了街道地址。解决办法:
在cin >> year;语句后面加cin.get();或者(cin >> year).get();
10、结构体的定义:
(1) 在定义时同时定义两个变量如:
struct perks
{
intkey_number;
charcar[12];
}mr_smith, ms_jones;
(2) 在定义时定义变量同时为它初始化:
struct perks
{
intkey_number;
charcar[12];
} mr_glitz =
{
7,
“Packard”
};
(3) 定义时不给结构体名称:
struct { int x; int y; } position;
11、结构体声明的位置
结构体声明的位置可以在函数体内即内部声明,也可在函数外面为外部声明,差别与变量的差别一样。
12、共用体
共用体也是一种数据结构,与结构体类似,声明也与结构体一样,但共用体中只能存储一种数据类型,如:
struct one
{
int int_val;
long long_val;
double double_val;
}
union two
{
int int_val;
long long_val;
double double_val;
}
在结构体中可以同时存储int_val、long_vale和double_val的值,但在共用体中只能存储int_val、long_val或double_val的值,也就是说只能为这三个变量的其中一个赋值。共用体的长度为其最大成员的长度。
13、 枚举
enumcolor{red, blue, yellow};
14、指针的理解
指针是一个变量,其存储的是值的地址,而不是值本身。对常规变量的取址使用‘&’符号,如int home = 5;则&home就为它所存储的地址。
例子:
#include<iostream>
int main()
{
using namespace std;
int higgens = 5;
int *pt = &higgens;
cout << “Value of higgens = ”<< higgens
<< “; Address of higgens = ”<< &higgens << endl;
cout << “Value of *pt = ” <<*pt
<< “; Value of pt = ” <<pt << endl;
}
打印结果:
Value ofhiggens = 5; Address of higgens = 0012FED4;
Value of*pt = 5; Value of pt = 0012FED4;
在声明语句中初始化指针,被初始化的是指针而不是它所指向的值,也就是说上面代码中是将pt(而不是*pt)的值设置为&higgens。
注意:int*p1, p2;表示声明了一个指针(p1)和一个int变量(p2)。
15、new与delete
当需要内存时,可以使用new来请求,是在程序运行时分配适当的内存,当使用完内存之后用delete来释放内存。
例1:int *ps = new int;//分配内存
delete ps;//释放内存
例2:int *psome = new int[10];//分配数组内存
delete [] psome;//释放内存
注意:用delete关键字只能释放new出来的内存。
为数组分配内存的通用格式:
type_name *pointer_name = new type_name[num_elements];
使用new运算符可以确保内存块足以存储num_elements个类型为type_name的元素,而pointer_name将指向第一个元素。
16、 动态数组的访问
int *psome= new int[3];
psome指向数组的第一个元素可以使用*psome访问,也可以使用psome[0]访问第一个元素,psome[1]访问第二个元素,psome[2]访问第三个元素…
17、指针与字符串
在cout和多数C++表达式中,char数组名、char指针以及用引号阔气的字符串常量都被解释为字符串第一个字符的地址。
charanimal[20] = “bear”;
char * ps;
ps =animal;
一般来说,如果给cout提供一个指针,它将打印地址。但如果指针的类型为char*,则cout将显示指向的字符串。如果要显示的是字符串的地址,则必须将这种指针强制转换为另一种指针类型,如cout << animal “ at ” << (int *) animal <<endl;输出结果为:bear at 0x0065fd30
打印ps:cout << ps “ at ” << (int *) animal <<endl
输出结果:bearat 0x0065fd30
从输出结果可以看出ps与animal共同指向了同一个地址。
如果先需要ps与animal指向的为不同的地址,可以使用strcpy(char*to, const char *from)方法,将animal字符串复制给ps,这样就得到了两个独立的副本。在使用strcpy()之前首先需要为ps分配内存:
ps = new char[20];
strcpy(ps, animal);
18、 句点运算符(.)与箭头运算符(->)的使用
在访问指定结构成员时,如果结构标示符时结构名,则使用句点运算符,如果结构标示符是指向结构的指针,则使用箭头,如:
structthings
{
int good;
int bad;
}
thingsgrubnose = {3, 453};//grubnose为结构名
things *pt= &grubnose;//pt为指向结构的指针
则在访问things成员时,grubnose使用grunbnose.good访问,pt使用pt->good访问。另一种访问方式是,由于pt是指向结构的指针,则*ps就是被指向的值—结构的本身,此时就可以使用(*pt).good来访问结构的成员。
19、自动存储、静态存储和动态存储(自由存储空间或堆)
在函数内部定义的常规变量使用自动存储空间,被称为自动变量,该变量在函数调用时自动产生,在函数结束时自动释放。自动变量通常存储在栈中,释放变量顺序为后进先出。
静态存储是整个程序执行期间都存在的存储方式,使变量称为金泰的方式有两种,一种是在函数外面定义它,另一种是在声明变量时加上static。
new和delete运算符为程序提供了动态存储的方式。new出来的变量放在堆内存中,用delete释放该对象的内存。
20、 数组、vector对象和array对象
vector是一种动态数组,可以在运行阶段设置vector对象的长度,可在末尾附加数据,还可以在中间插入新数据。
使用实例:
#include<vector>
…
usingnamespace std;
vector<int>vi;
int n;
cin>> n;
vector<double>vd(n);
在上面的示例中其中n表示vector的长度,可以看出vector的长度可以是整型常量,可以没有(默认为0)也可以是整形变量。在存储vector对象时是在堆内存中。
array对象与数组一样,长度必须得固定,即长度一定为整型常量,为array对象分配的内存位于栈内存中,因此效率与数组一样,但比数组更方便、安全些。
使用示例:
#include<array>
…
usingnamespace std;
array<int,5> ai;
array<double,4> ad = {1.2, 2.1, 3.43, 4.3};
array通用的创建方法归纳为:array<typeName, n_elem> arr;其中typeName表示数组中所存放的数据类型,n_elem表示长度。