C++学习之初步
来源:互联网 发布:网络音乐游戏排行榜 编辑:程序博客网 时间:2024/06/03 02:27
本人学习C++有段时间了,但是对C++还是有些部分不是很了解。因此专门找了本讲解C++的书籍,边看边总结,希望能增加对C++的理解。该书的名字是《C++面向对象程序设计》,作者李晋江,刘培强。选择该书的原因是:它是一本面向教学的书籍,里面的知识讲解都很清晰明了。本人打算先增加下对C++的理解,再去拜读下那些权威名著。
第一部分:C++语言初步
1. 命名空间
1). C++中的命名空间是用于避免类名的冲突,尤其会在大型的项目中体现出重要的作用。C++采用的是单一的全局变量命名空间。命名空间的定义:
namespace mynamespace //命名空间名字,可以自己定义,但不能与其他命名空间重名
{
int i;
classmyclass //以上是内部定义方法
{
};
void func1();
…….
}
当然也可以选择外部定义的方法,但必须要先在命名空间内部声明,例如上面的func()函数,在命名空间内只对其做了声明而没有定义。因此
void mynamespace::func1() {i++;} //选择外部定义的方式
如果要为已定义的命名空间增加成员应该怎么办呢?因为命名空间是开放的,因此命名空间可以通过多次声明和定义同一命名空间,每次添加自己的新成员和名称来实现。如:
namespace mynamespace
{
int j;
voidfunc2();
}
切记:不可对std的命名空间增加或删除任何成员。
2).如果使用命名空间?
命名空间有三种使用方法:(1)usingnamespace mynamespace; 即using namespace 加上命名空间的名字。(2)using mynamespace::member; 即using 加上命名空间的名字::成员。(3)直接在使用命名空间内的成员时加上该命名空间的名字。如我们在使用cout时可以用std::cout表示。上面三种方法在使用的时候各有优缺点,第一种方法可以减少编程人员的输入,但有可能会引起命名冲突;第三种方法需要很多的输入;第二种方法是以上两种方法的折中,但如果使用不当也可能会造成冲突。
需要注意的几点:
命名空间可以是没有名字的:如
namespace
{
members;
}
其作用是将成员局限于一个特定的文件,不能跨越多个文本文件。
可以为命名空间取个别名:如
namespace mynamespace = mns;
不同的命名空间可以进行组合和选择;如果不同命名空间使用在同一程序中,他们间的函数可以实现重载。
2. 输入和输出
C++中实现流简单输入和输出的是iostream 对象cin和cout;而且cin和cout也是比较熟悉的。同C语言提供了格式化输入输出的方法,C++也提供了输入输出的控制符。
首先先说说cout:
cout做为一个iostream对象,可以使用setf()/unsetf()或flags()成员函数设置格式。
其常用的输出格式包括以下几种:
ios::dec 十进制输出
ios::hex 十六进制输出
ios::oct 八进制输出
ios::showbase 添加一个表示其进制的前缀
ios::internal 使输出字符串两端对齐
ios::left 左对齐
ios::right 右对齐
ios::boolalpha 将bool类型的值以true/false输出
ios::fixed 将浮点数按照普通定点格式处理
ios::scientific 将浮点数按照科学计数法处理
在头文件<iomanip>头文件中也包括一些输入输出的控制符,常用的包括:
setw(int num); 用当前的填充字符控制对齐位置,默认的填充字符是空格
setfill(char ch); 设置填充字符
setprecision(int num); 设置输出精度
在输出流中有一个函数endl,该函数等价于<<”\n”<<flush,即先输出一个换行符,再实现缓冲区的刷新。flush是刷新流,在C语言中用ffush(FILE* stream)实现。
同时介绍一个打开和关闭缓冲的机制:setbuf(FILE *stream, char *buf);把缓冲区与流相关联。
#include<iostream>
#include<iomanip>
#include<windows.h>
using namespace std;
int main()
{
char* pbuffer = new char[1024];
setbuf(stdout,pbuffer);
cout<<"hello world";
Sleep(1000);
cout<<"hello world";
Sleep(1000);
cout<<"helloworld"<<flush;
delete pbuffer;
return 0;
}
该例程的输出结果是:
hellow worldhello worldhello world
其次介绍下cin输入。
下面主要介绍下cin的一些成员函数,cin.get() ; cin.getline(); cin.clear(), cin.sync(); cin.rdstate()。
cin.get()是一个读取单个字符的方法。
cin.getline(char *line, int size, char ch);获取一整行文本,第三个参数是结束标识符
然后cin.rdstate()使用来检测输入错误的,它可以返回四种结果:
ios::goodbit 流状态正常
ios::badbit 流出现致命错误,不可挽回
ios::eofbit 已经到达文件尾
ios::failbit 流出现非致命错误,可挽回
当流出现非致命错误,即ios::faibit时可以通过cin.clear()// 清除错误位和cin.syc()//清空流。来操作实现流的重新输入。
3. string类型
string类型包含在头文件<stirng>中,这里要注意是<string >而不是<string.h>;后者是C语言中的字符串头文件。
string类型可以理解为是C语言中字符串数组的进化版本。string类具有多个成员函数,因此它可以实现不同的操作。
首先是初始化一个string类型:string类型有多种构造函数,以及复制构造函数和copy assignment 操作符。
如:
string str; default constructor
str = “Hellow world”; copy assignment operator
char cstr[] = “abcde”; C 字符串
string s1(str); // copy constructor
string s2(str, 6);// 将str内,开始位于位置6的部分当做s2的初值
string s3(str, 6,3);//将str内,开始位于位置6且长度最多为3的部分作为s3的初值
string s4(cstr);
string s5(cstr, 3);// 将C字符串前3个字符作为字符串s5的初值
string s6(5, ‘A’); //生成一个字符串,包含5个’A’字符
需要注意的是:
不可以提供以字符和正数为参数的构造函数,即
string error1 = ‘C’; // error
string error2(‘u’); // error
但是可以先定义str对象,然后用字符对其赋值,如
string str ;
str = ‘A’;//这样是正确的。
string类型的比较等操作。C++string类型对==,>, <, >=, <= 和!= 以及 + , +=, []操作符都做了重载,可以实现string类型数据的比较。其中[]操作符,可以用成员函数at()替代。而且str.at(i)提供了范围检查,当越界时会抛出out_of_range异常。当然遍历string类型数据也可以用迭代器iterator;而且str.begin() str.end()和str.rbegin() str.redn()分别实现了string数据类型的正反方向的遍历。
string类还提供了一些其它的成员函数,比如特性描述,查找等方面的成员函数
1).string特性描述
intcapacity() const;// 返回当前容量
intmax_size() const;// 返回string对象中可存放的最大字符串的长度
intsize() const;// 返回当前字符串的大小
intlength() const; // 返回当前字符串的长度
boolempty() const;// 当前字符串是否为空
voidresize(int len, char c);// 把字符串当前大小设置为len,多去少补,并由字符c填充//多出的部分
2). string的查找
size_typefind (const basic_string &str, size_type index);
//返回str在字符串中第一次出现的位置(从index开始查找),否则返回string::npos
size_typefind (const char*str, size_type index); // 同上
size_typefind(const char*str, size_type index, size_type length);
//返回str在字符串中第一次出现的位置(从index开始查找,长度为length),否则返回//string::npos
size_typefind(char ch, size_type index);//查找字符在字符串第一次出现的位置
3). 其它常用函数
string& insert(int p, const string &s);
string&replace(int p, int n, const char *s);//p为起始位置,n为长度(下同)
string&erase(int p, int n);
stringsubstring(int pos =0, int n = npos) const;
voidswap(string &s2);
string&append(const char *s);
voidpush_back(char c);
constchar* data() const;// 返回一个非NULL终止的c字符串
constchar* c_str() const;// 返回一个NULL终止的c字符串
以上函数从函数名就可以判断出它们的作用。
4. new和delete
new和delete 用于内存的动态管理。其与C语言的malloc和free有一定的区别。虽然它们都是用于内存的动态管理。但是malloc和free是C语言中的函数,new和delete是操作符。因此它们在使用的时候也会有不同的地方。典型的是对非内部类型数据的内从的动态管理。malloc和free是适合于内部数据类型的分配和销毁。但是对于非内部的数据类型,比如一个类,malloc函数只会分配一定的内存空间,但不会调用类的构造函数,free也不会调用类的析构函数。而new和delete作为运算符,可以用于重载,它是可以实现类在动态分配时调用它的构造和析构函数。(可以编写一个类做验证)
需要注意的是malloc和new在分配内存的时候会产生失败。其中malloc产生失败是会返回NULL的指针值;而new则有两种情况:1).默认情况下会抛出异常;2).但也可以include头文件<new>,其中包含了一个不抛出异常的new,即T *p = new(nothrow())T[MAX_SIZE]。综上所述在使用malloc和new时要对内存是否分配成功进行判断。
对于malloc和不抛出异常的new的判断方法是一样的:
#include <new>
int *p_int = new(nothrow)int [len];
if(NULL == p_int)
if(NULL == p)
{
cout<<”memory allocate error!”<<endl;
return -1;
}
char *p = (char *)malloc(len*sizeof(char));
if(NULL == p)
{
cout<<”memory allocate error!”<<endl;
return -1;
}
而对于抛出异常的new,要做异常的捕捉。
try
{
int *p_int = new int[len];
}
catch(const bad_alloc&e)
{
return -1;
}
接着简述下栈和堆的区别:
栈,就是由编译器在需要的时候分配的,里面的变量通常是局部变量,函数参数等。
堆:就是由malloc或new分配的内存块,它的释放不是由编译器释放的,而是应该由free和delete去释放的。
两者的区别可以总结为一下几点:
1) 管理方式和碎片问题: 栈是由编译器管理的,它是一个先进后出的队列,是不会产生碎片的。而堆是由程序动态的分配和释放内存,频繁的分配和释放内存势必会造成内存空间的不连续,从而产生大量碎片。
2) 分配效率:栈是系统提供的数据结构,计算机为其分配了专门的寄存器存放栈地址,因此它的效率是比较高的。而堆则是C/C++提供的一种内存机制,它的效率比栈低。
3) 增长方式:栈的内存地址的增长方式是从高地纸到低地址增长的,开辟栈时,栈指针向低地址方向增长,回收栈时,栈指针向高地纸方向移动。而堆来讲,它的增长方式是向上的,分配时向高地址移动,回收时向低地址移动。对于32位系统来说,堆可以达到4GB的内存空间,而栈一般都是有一定的空间大小的。
- C语言初步学习记录之三
- Objective-C 初步学习
- 初步学习c语言
- C语言学习之对数组元素初步排序
- C++学习之初步
- Process之初步学习
- JMS之初步学习
- c++之初步学习
- c语言初步学习记录
- C语言初步学习笔记
- alloc.c初步之数据结构
- AT命令之初步学习
- WPF学习之初步了解
- 正则表达式之初步学习
- UML学习之初步总结
- C++学习之初步了解
- Android学习之Activity初步
- Android学习之View初步
- [LeetCode] 逆波兰表达式求值
- 占位
- 占位
- 虚拟化系列-Citrix XenServer 6.1 安装与配置
- 雅虎给出的34条网站加速方法
- C++学习之初步
- Android中的Service 与 Thread 的区别
- 关于VS2010 的command arguments
- testng参数化测试
- SQL实现字符串的拼接
- iOS 全景
- 当查询没有数据返回时返回一行默认值sql
- uva 1419 Ugly Windows
- 占位