保持快乐,善于表达,敢于创新

chapter3---c++ 内部类型

上一篇 / 下一篇  2011-08-19 18:19:23 / 个人分类:c++

3.1 global and local:

Global:一个简单的定义指定了变量的类型和标识符 它并不提供初始值 如果一个变量是在全局域global scope内定义的那么系统会保证给它提供初始值0

local: 如果变量是在局部域local scope 内定义的, 或是通过new表达式动态分配的则系统不会向它 提供初始值0这些对象被称为是未初始化的uninitialized未初始化的对象不是没有值 而是它的值是未定义的undefined与它相关联的内存区中含有一个随机的位串可能 是以前使用的结果.

3.2 extern

extern vector<string> students; 不分配内存单元,只是声明此为外部对象。

vector<string> students; 分配内存单元。

3.3 pointer

void*空类型指针,表明相关的值是个地址 但该地址的对象类型不知道。所以任意类型的指针可以付给void*,但反之则不行。
int *p=0; 分配一个整型指针,不指向任何对象地址。
int i =22; 分配一个整型对象,把22付给此对象
p=&i;  将整型对象的地址付给p,这样p的指针就指向此对象。
void *pv;分配一个指针,但类型不知。
pv=p;将p的指针付给此void对象
p=pv; 错误, 不能将void指针付给整型指针。

3.4 cstring

cstring 是c 语言的字符串格式,他用字符数组表示,在尾部用null来表示结束。

const char *st = "The expense of spirit\n";

cout << st: //print the st string.

系统在内部也把字符串常量存储在一个字符串数组中,然后st指向该数组的第一个元 素。

使用cstring时候注意的是所有操作函数的参数都是指针,字符串尾部有个不可见的null元素, *st表示第一个字符,而不是字符串内容。

3.5 string

string: 字符串类。
初始化:string st(“aaa“);
访问st中某个字符 st[i];第i个字符
是否为空: st.empty()
是否相等:st==sw;
字符串联接:st +=”aa”;
将cstring付给string:const char *cst=“good”;
string st=cst;
将string付给cstring: const char *cst = st.c_str();
3.6 const

const int *p: p可以存任何int的地址,但不能通过*p来改变p所指向对象的值。(常用,用于函数形参)。
int *const p: 表示p所存储的地址值不能改, 但int p所指向的地址存的值是可以被改变的。
const int *const p:p所指向的地址和指向的地址里面的值都不可被改。

3.7 引用

引用就是变量名的别名,其实他是此变量名所在的地址,用一个别名代替此地址,所以声明时候必须初始化,否则是错误的。如:
int value=34;
int &ref = value;  //编译器并没有分配内存,而ref就是此value的所在地址的别名。
ref=10;

int *&ref = &value; //分配一个指针地址&ref,其指向的地址是value对象的地址。

特别:

const引用可以用不同类型的对象初始化,只要能从一种类型转换到另一种类型即可,也可以是不可寻址的值 。如文字常量例如:

double dval = 3.14159;

//仅对于const引用才是合法的 

const int &ir = 1024; 

const int &ir2 = dval; 

const double &dr = dval + 1.0;


也就是说:可以直接对const的引用对象付值。

但同样的初始化对于非const引用是不合法的,将导致编译错误

对于const的类型引用直接付初始值,是因为编译器为此const生成一个暂时变量tmp,他处理如下:

int tmp =1024;

const int &ir= tmp;

3.8 bool:

1. bool 值参加整数运算时,可以自动转换为整型值。true 表1,false表0;
2. if(found==true)可缩写为 if(found
3。算术和指针能隐式地被转换为bool,0和null表示false,其他表示true

3.9 枚举:

枚举enumeration提供了一种替代的方法 它不但定义了整数常量 而且还把它们组 成一个集合 例如

enum open_modes{ input = 1, output, append };//input=1,output=2,append=3;

void open_file( string file_name, open_modes om );//om只能取上面的三个值之一。


// point2d == 2, point2w == 3, point3d == 3, point3w == 4

enum Points { point2d = 2, point2w, point3d = 3, point3w };//后一个元素以前一个值加1,如果没有初始值,那么第一个元素值为0;


枚举值只能同元素才可以付值,如下:

points point2w=point3d //ok 两个元素都是枚举值

points point2w=3 //错误,不能把值付给枚举

3.10 数组

1. 维数值必须是常量表达式——即必须能在编译时刻计算出它的值,这意味着非const的变量不能被用来指定数组的维数. 数组在初始化时候,必须知道他的维数是多少。

const int buf_size = 512, max_files = 20; //编译时候,const可以分配数值

char input_buffer[ buf_size ];//因为在编译时候,维数已经有值为512,所以数组知道分配512个空间。

int staff_size = 27; //编译时候,并会分配内存。

double salaries[ staff_size ];//错误, 因为编译时,不知staffsize是多少,只有运行时候知道.

2.

数组元素是从0开始计数的,对一个包含10个元素的数组,正确的索引值是从09而不是从110

3.

被显式初始化的数组不需要指定维数值 编译器会根据列出来的元素的个数来确定数组 的维数

//维数为3的数组
int ia[] = { 0, 1, 2 }


4. 如果指定了维数 那么初始化列表提供的元素的个数不能超过这个值 否则 将导致编

译错误. 如果指定的维数大于给出的元素的个数, 那么没有被显式初始化的元素将被置为 0

// ia ==> { 0, 1, 2, 0, 0 }

const int array_size = 5; 


int ia[ array_size ] = { 0, 1, 2 };

5. 一个数组不能被另外一个数组初始化,也不能被赋值给另外一个数组. 而且 C++不允 许声明一个引用数组(即由引用组成的数组)

int ix, jx, kx;

// ok: 类型为 int*的指针的数组 

int *iap [] = { &ix, &jx, &kx };


// 错误不允许引用数组 

int &iar[] = { ix, jx, kx };

6. Vector

1.数组习惯

vector< int > ivec( 10 ); //定义含有10个元素的容器

vector< int > ivec( 10, -1 ); //有10个元素,每个元素都是-1;


vector< string > svec; //声明一个容器

vector< string > user_names( svec ); //用svec容器初始化user name容器。

svec = user_names; //把user name容器付给svec容器。

2。stl习惯 

不是定义一个已知大小的vector而是定 义一个空vector:

vector< string > text;

用push_back()操作在vector的后面插入一个元素。

用下标访问容器中每个元素

vector< string > text;

for ( int ix = 0; ix < text.size(); ++ix )

 cout << text[ ix ] << ' ';

利用容器的迭代指针访问:

for ( vector<string>::iterator it = text.begin();

 it != text.end(); ++it )

cout << *it << ' ';  //遍历每个元素值

任何一个插入操作都将增加vector的大小而不是覆盖掉某个现有的元素

下面是常见错误,把stl用法和传统的数组用法混用造成。

const int size = 7; 

int ia[ size ] = { 0, 1, 1, 2, 3, 5, 8 }; 

vector< int > ivec( size );   //已经分配7个单元元素地址,初值为0;

for ( int ix = 0; ix < size; ++ix )

 ivec.push_back( ia[ ix ]); //在第7个元素后面又插入7个,而不是覆盖前面的7个元素值。

程序结束时ivec包含14个元素,ia的元素从第八个元素开始插入。

7. typedef

1. typedef char *cstring;
   
extern const cstring cstr;
   
const char *cstr //指向const字符的指针,这是不正确的.正确的是这样的:
      char *const cstr;//
const修饰cstr的类型, cstr是一个指 针.因此这个定义声明了cstr是一个指向字符的const指针.

 8.overwrite operator


#ifndefSTRING_H_

#defineSTRING_H_

#include<iostream>

#include<cstring>

#include<cassert>

#include<iomanip>

#include<string>

usingnamespacestd;

classString;


istream& operator>>(istream&,String& );

ostream& operator<<(ostream&,constString& );

classString{

public:

String(){

_size= 0;

_string= 0;

}

String(constchar* str){

if(!str){

_size= 0;

_string= 0;

}

else{

_size=strlen(str);

_string=newchar[_size+1];

strcpy(_string,str);

}

}


String(constString& str){

_size=str._size;

if(!str._string){

_string=0;

}

else{

_string=newchar[_size+1];

strcpy(_string, str._string);

}

}


~String(){

delete_string;

}


intsize(){

return_size;

}


char* cstr(){

return_string;

}


boolperator==(constString&);

boolperator==(constchar*);


String& perator=(constString&);

String& perator=(constchar*);

char& operator[](int);

friendostream& operator<<(ostream&,constString& );

private:

char*_string;

int_size;

};


inlineString& String::operator =(constchar* pch){

if(!pch){

_size=0;

delete[]_string;

_string=0;

}

else{

_size=strlen(pch);

_string=newchar[_size+1];

strcpy(_string,pch);

}

return*this;

}


inlineString& String::operator =(constString& str){

if(this!= &str){

delete[]_string;

_size=str._size;

if(!str._string){

_string=0;

}

else{

_string=newchar[_size+1];

strcpy(_string,str._string);

}

}

return*this;

}


inlineboolString::operator==(constchar* pch){

if(strlen(this->_string) !=strlen(pch))

returnfalse;

for(inti=0; i<_size; i++)

if(this->_string[i] != pch[i])returnfalse;

returntrue;

}


inlineboolString::operator==(constString&str){

if(_size!=str._size)returnfalse;

returnstrcmp(_string, str._string)?false:true;

}


inlinechar& String::operator[](intch){

assert(ch>0 && ch<_size-1);

return_string[ch];

}


inlineistream& operator>>(istream&io,String&s ) {

constintlimit_string_size = 4096;

charinBuf[ limit_string_size ];

io >> setw( limit_string_size ) >> inBuf;

s = inBuf;

returnio;

}


inlineostream& operator<<(ostream& os,String&s ) {

returnos << s.cstr();

}



#endif/* STRING_H_ */


TAG:

 

评分:0

我来说两句

Open Toolbar