7.字符串和向量
a.字符串是一种数组类型
%1.c字符串值和c字符串变量
假定字符串是"hello",则需要一个6个引索变量的字符数组,最后一个位置用来存放‘\0‘。‘\0‘为一个空字符,用于表征字符串的结束。
注意:以下两个声明方式并不一致:
char short_string[] = ‘abc‘;
char short_string[] = {‘a‘,‘b‘,‘c‘};
前者会在abc后有一个‘\0‘,而后者却没有。
注意:char a[3];
a="er"; //这一语句是非法的。对于字符串,除了在声明时可以赋值之外,不能以这样的方式赋值。
想要调用c++提供的字符串函数,需要#include <cstring>
atoi函数可以将字符串转为数字。eg:atoi("1234"); //将返回整数1234。 使用需要 #include<cstdlib>
b.标准string类
%1.标准string类简介
想要使用string类,必须包含:
#include<string>
using namespace std;
声明方式:
string noun = "name";
phrase = "I love "+ noun +"!";
string s1 ,s2("hello");
%2.string类的I/O
考虑如下代码
string c1 , c2;
cin >> c1 ;
cin >> c2 ;
如果用户输入: May the hair on your toes grow long and curly!
这样s1获得May,s2获得the;
如果希望程序将整行输入读入一个string类型的变量,那么可以使用getline函数。在#include<string>下:getline的用法有所不同,不能使用cin.getline
而是:string line;
getline(cin,line);
cin与getline的混用可能会出现问题。
%3.可以用string类进行字符串处理
string类中包含一些成员函数,利用这些函数可以简化字符串的处理。string定义的字符串,可以用数组的访问方式访问。
%4.将string类转换为c字符串:
eg:char a_c_string[];
string string_variable = "cstring";
strcpy(a_c_string,cstring.c_str());
c.向量:
%1.向量的基础知识
为了将变量v声明为基类型为int的一个向量,如下:
#include <vector>
vector<int> v;
向量的索引号从零开始,虽然可以用v[i]来访问向量中相应位置的值,可是无法用这种方式对他进行初始化。要为相应的索引位置首次添加值,要使用成员
函数push_back。在向量中添加元素是要依次添加,首先添加位置0,位置1,位置2;
eg:vector<double> sample;
sample.push_back(0.0);
sample.push_back(1.1);
sample.push_back(2.2);
向量中的元素个数称为向量的长度(size),可以用成员函数size判断向量中有多少个元素。
8.指针和动态数组:
a.指针:指针是内存变量的地址
%1.指针变量
double *p; //声明了一个指向double型变量的指针。
int *p1,*p2,v1,v2; //可以将指针和普通变量一起声明。
下面的语句可以让指针指向变量:
p1=&v1;
在此之后*p1和v1拥有完全同样的属性。异
指针中注意对于*和&的使用。时刻注意p1=p2;与*p1=*p2的差别。 操作符new?
%2.基本内存管理
操作符delete可以销毁一个变量,将他占用的空间返还给自由存储。
eg: delete p;
编程时可以定义指针类型:
eg: typedef int* IntPtr;
IntPtr p; //这里与int *p是等价的;
b.动态数组 动态数组是写程序时不指定长度的一种数组,他的长度实在程序运行时确定的。
%1.数组变量和指针变量
int a[10];
int *p;
p=a;
p[0],p[1],...与a[0],a[1],...有相同的作用。
%2.创建和使用动态数组
double *a;
a=new double[array_size]; //array_size是一个int型的变量,其值在程序运行的过程中给出。
delete [] a; //销毁动态数组。
9.定义类
a.结构
%1.用于异种数据的结构:
结构定义如下:
struct CDAccount
{
double balance;
doubel interest_rate;
int term;
};//注意这个地方的分号
其中关键字struct宣布这是一个结构类型定义。标识符CDAccount是结构类型的名称。两个或更多的结构类型可以使用相同的结构名称。
%2.结构作为函数参数
对于一个函数来说,它可以有结构类型的传值调用参数,或者结构类型的传引用参数。
函数的返回值也可以是一个结构。
eg: CDAccount shrink_warp(double the_balance,double the_rate,int the_term)
{
CDAccount temp;
...
return temp;
}
%3.对结构进行初始化
struct Date
{
int mouth;
int day;
int year;
};
Date due_date = {09,06,2015};
b.类
%1.定义类和成员函数
类(class)是一个数据类型,它的变量就是对象。
eg: class DayOfYear
{
public:
void output();
int day;
int month;
}; //注意此处的分号
void函数可以在c++文件中定义,定义的方式是
void DayOfYear::output()
{
cout << "month=" << month
<< "day=" << day << endl;
}
类的声明方式:DayOfYear today;
调用函数的方式是 today.output();
%2公共成员和私有成员
私有成员即除非在一个成员函数的定义内,无法在程序的任何地方直接访问他们。私有成员的定义方式是:
class DayOfYear
{
public:
void output();
int getday();
int getmonth();
private:
void check_date(); //私有成员函数
int day; //私有成员变量
int month; //私有成员变量
};
关于类的编程可以给出以下的几点提示:
first.将所有的成员变量设为私有;
second.对于每一个类编写取值函数get和赋值函数set;
%3.将操作符用于对象:
DayOfYear due_date,tomorrow;
建立在这个定义的基础上,以下的语句是合法的:
due_date=tomorrow; //这其中的私有变量也会被赋值。
%4.用于初始化的构造函数
声明对象时,经常需要初始化它的部分或全部变量。为此,定义一个类时,可定义一种特殊的函数,被成为构造函数。构造函数是一个成员函数,会在声明一个函数
时被自动调用。构造函数用于初始化变量的值,并进行任何可能需要的初始化操作。使用构造函数的时候需要注意以下几点:
first:构造函数必须与类同名。
second:构造函数的定义不能返回一个值。此外,在函数声明的起始处或者函数头中,不许指定返回类型(就连void都不可以)。
third:构造函数要放在public小节。
初始化构造函数可以有以下的声明方式:
BankAccount::BankAccount():balance(0),interest_rate(0.0)
{
//主体有意留空;
}
对于这样的定义:初始化的方式应为 BankAccount account; 这样才是正确的。
或者:
BankAccount::BankAccount(int dollar,int cents,double rate):balance(dollars+0.01*cent),interest_rate(rate)
{
if((dollar<0)||(cents<0)||(rate<0))
{
exit(0);
}
}
c.抽象数据类型
%1.用于生成抽象数据类型的类
数据类型由值的一个集合以及那些值定义的一系列基本运算构成。如果使用一个数据类型的程序员不能访问值和运算的细节,这个数据类型就称为抽象数据类
型(ADT);
程序员的定义的类型不会自动的成为ADT,而程序中最好能够实现程序员所有定义的数据类型都为ADT。为了使一个类变成ADT,必须采取特定的方式来定义类。
为了将类定义成抽象数据类型,你需要严格区分程序员使用类型的方式与该类的实现细节。
为了达到的这个目的,需要遵守一下的原则:
first:将所有的成员变量设为私有变量。
second:将用户程序员需要的每个基本操作设为公共成员函数,并完善地指定如何使用每个公共成员函数。
third:将任何辅助函数都设为私有成员函数。
d.继承
流类之间的继承关系:
C++最强大的特性之一就是派生类的使用。
我们说类A是类B的派生类时,是指类A具有类B的全部特性,但它还可能新添了一些特性。ifstream是istream的派生类。
void say_hello(ostream& any_out_stream)
{
any_out_stream << "hello";
}
调用的时候可以采用以下的方式:
ofstream fout;
fout.open("afiled.at");
say_hello(cout); //这样使用是因为ofstream是ostream的派生类。
say_hello(fout);