C++ 知识点2

1>:二进制文件进行IO操作
在对二进制文件进行IO操作时,打开文件时要指定方式ios::binary,即以二进制形式传送和存储。接下来我用read函数和write函数来对二进制文件进行读写。在示例描述之前先简单介绍一下这两个函数:


  read函数常用格式为:文件流对象.read(char *buf,int len);


  write函数常用格式为:文件流对象.write(const char *buf,int len);


两者格式上差不多,第一个参数是一个字符指针,用于指向读入读出数据所放的内存空间的其实地址。第二个参数是一个整数,表示要读入读出的数据的字节数


在read函数还是write函数里都要把数据转化为char*类型


在文件结束处有个标志位EOF,在用文件流读取文件时,使用成员函数eof()(函数原型:int eof())可以检测到结束符。如果该函数返回值为非零,则表示到达文件末尾。返回零则表示未达到文件末尾。


 (3)前面所介绍的文件都是按顺序来读取的的,C++中又提供了针对于文件读写指针的相关成员函数,使得我们可以在IO流中随意移动文件指针,从而对文件的进行随机地读写。类istream针对读指针提供3个成员函数:


  tellg()//返回输入文件读指针的当前位置;
  seekg(文件中的位置)//将输入文件中的读指针移动到指定位置
  seekg(位移量,参照位置)//以参照位置为基准移动若干字节


其中参照位置是枚举值:
beg//从文件开头计算要移动的字节数
cur//从文件指针的当前位置计算要移动的字节数
end//从文件的末尾计算要移动的字节数
如果参照位置省略,则默认为beg。而类ostream针对写指针提供的3个成员函数:


  tellp()//返回输出文件写指针的当前位置;
  seekp(文件中的位置)//将输出文件中的写指针移动到指定位置
  seekp(位移量,参照位置)//以参照位置为基准移动若干字节




2>:C++ STL算法系列之:copy
template<class InputIterator, class OutputIterator>  
   OutputIterator copy(  
      InputIterator _First,   
      InputIterator _Last,   
      OutputIterator _DestBeg  
);  
参数
_First, _Last
指出被复制的元素的区间范围[ _First,_Last).
_DestBeg 
指出复制到的目标区间起始位置
返回值
返回一个迭代器,指出已被复制元素区间的最后一个位置
该算法 可用于 数组 向量 等




3>:C++ STL 容器:vector


一、 定义和初始化


vector< typeName > v1;       //默认v1为空,故这赋值是错误的v1[0]=5;
vector<typeName>v2(v1); 或v2=v1;或vector<typeName> v2(v1.begin(), v1.end());//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被扩充为v1.size()。
vector< typeName > v3(n,i);//v3包含n个值为i的typeName类型元素
vector< typeName > v4(n); //v4含有n个值为0的元素
int a[4]={0,1,2,3,3}; vector<int> v5(a,a+5);//v5的size为5,v5被初始化为a的5个值。后一个指针要指向将被拷贝的末元素的下一位置。
vector<int> v6(v5);//v6是v5的拷贝
vector< 类型 > 标识符(最大容量,初始所有值);




二、vector对象最重要的几种操作
1. v.push_back(t)    在容器的最后添加一个值为t的数据,容器的size变大。
    另外list有push_front()函数,在前端插入,后面的元素下标依次增大。
2. v.size()        返回容器中数据的个数,size返回相应vector类定义的size_type的值。v.resize(2*v.size)或                v.resize(2*v.size, 99) 将v的容量翻倍(并把新元素的值初始化为99)
3. v.empty()     判断vector是否为空
4. v[n]           返回v中位置为n的元素
5. v.insert(pointer,number, content)    向v中pointer指向的位置插入number个content的内容。
    还有v. insert(pointer, content),v.insert(pointer,a[2],a[4])将a[2]到a[4]三个元素插入。
6. v.pop_back()    删除容器的末元素,并不返回该元素。
7.v.erase(pointer1,pointer2) 删除pointer1到pointer2中间(包括pointer1所指)的元素。
   vector中删除一个元素后,此位置以后的元素都需要往前移动一个位置,虽然当前迭代器位置没有自动加1,
   但是由于后续元素的顺次前移,也就相当于迭代器的自动指向下一个位置一样。
8. v1==v2          判断v1与v2是否相等。
9. !=、<、<=、>、>=      保持这些操作符惯有含义。
10. vector<typeName>::iterator p=v1.begin( ); p初始值指向v1的第一个元素。*p取所指向元素的值。
      对于const vector<typeName>只能用vector<typeName>::const_iterator类型的指针访问。
11.p=v1.end( ); p指向v1的最后一个元素的下一位置。
12.v.clear()      删除容器中的所有元素。




我觉得可以把vector的类型定义写成public
然后写个protected的指针
比如


public:
typedef std::vector<...> MYVECTOR;
protected:
MYVECTOR m_vector;




13.vector.insert()用法:
iterator insert( iterator loc, const TYPE &val ); 
void insert( iterator loc, size_type num, const TYPE &val ); 
void insert( iterator loc, input_iterator start, input_iterator end ); 


insert() 函数有以下三种用法: 


在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器, 
在指定位置loc前插入num个值为val的元素 
在指定位置loc前插入区间[start, end)的所有元素 . 
举例: 


//创建一个vector,置入字母表的前十个字符 
vector <char> alphaVector; 
for( int i=0; i < 10; i++ ) 
  alphaVector.push_back( i + 65 ); 


//插入四个C到vector中 
vector <char>::iterator theIterator = alphaVector.begin(); 
alphaVector.insert( theIterator, 4, 'C' ); 


//显示vector的内容 
for( theIterator = alphaVector.begin(); theIterator != alphaVector.end(); theIterator++ ) 
  cout < < *theIterator; 


这段代码将显示:


CCCCABCDEFGHIJ










4>:C++ STL 容器:map






5>:C++中pair


 pair的应用
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。


2 make_pair函数


template pair make_pair(T1 a, T2 b) { return pair(a, b); }


很明显,我们可以使用pair的构造函数也可以使用make_pair来生成我们需要的pair。 一般make_pair都使用在需要pair做参数的位置,可以直接调用make_pair生成pair对象很方便,代码也很清晰。 另一个使用的方面就是pair可以接受隐式的类型转换,这样可以获得更高的灵活度。灵活度也带来了一些问题如:


std::pair<int, float>(1, 1.1);


std::make_pair(1, 1.1);


是不同的,第一个就是float,而第2个会自己匹配成double。


举例:
pair 通常作为map的迭代器出现的吧
map<string, int> word_count;
pair<string,int> p_count;
p_count = make_pair("word",3);//make_pair(),返回一个pair类型
cout << p_count.first << endl;   //输出p_count的key,也就是"word";
cout << p_count.second << endl;  //输出p_count的value,也就是3
word_count.insert(make_pair("word1",2));
map<string, int>::iterator mit;
mit = word_count.begin();
cout << mit->first << endl;
cout << mit->first << endl;  //分别输出“word1”,和2






6>:原型:void *memmove( void* dest, const void* src, size_tcount );
由src所指内存区域复制count个字节到dest所指内存区域。
src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针。\








7>: std::string 


string s
//find 函数 返回jk 在s 中的下标位置   
position = s.find("jk");  
 if (position != s.npos)  //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,  
 
//find 函数 返回flag 中任意字符 在s 中第一次出现的下标位置   
 flag = "c";
 position = s.find_first_of(flag);  
 


//从字符串s 下标5开始,查找字符串b ,返回b 在s 中的下标  
position=s.find("b",5);   
 
//查找flag 中与s 第一个不匹配的位置  
flag="acb12389efgxyz789";  
position=flag.find_first_not_of (s); 
 
 
//反向查找,flag 在s 中最后出现的位置  
 flag="3";  
 position=s.rfind (flag);  
 
  说明:
1.如果string sub = ”abc“;
       string s = ”cdeabcigld“;


    s.find(sub) , s.rfind(sub) 这两个函数(默认从头找),如果完全匹配,才返回匹配的索引,即:当s中含有abc三个连续的字母时,才返回当前索引。
s.find(sub,index)查找sub 从index开始
s.find_first_of(sub),   s.find_first_not_of(sub),   s.find_last_of(sub),  s.find_last_not_of(sub)  这四个函数,查找s中含有sub中任意字母的索引。


2.如果没有查询到,则返回string::npos,这是一个很大的数,其值不需要知道。

//string::compare
如果所比较的两个string 相等,则返回0; 操作string 大于参数string,返回
正数;操作string 小于参数string,返回负数。
(1)比较操作string 与_Str 或C-string_Ptr
int compare( const string& _Str ) const;
int compare( const char* _Ptr ) const;
int com = s.compare ( sp );
(2)比较操作string 中_Pos1(下标)开始的_Num1 个字符 与 string_Str
比较操作string 中_Pos1(下标)开始的_Num1 个字符 与 C-string _Ptr
比较操作string 中Pos1(下标)开始的Num1 个字符 与Str 中Off(下标)开始Count 个字

int compare( size_type _Pos1, size_type _Num1, const string& _Str );
int compare( size_type _Pos1, size_type _Num1, const char* _Ptr ) const;
int compare( size_type _Pos1, size_type _Num1, const string& _Str,
size_type _Off, size_type _Count );
int com1 = s.compare ( 2 , 3 , sp );
int com2 = s.compare ( 2 , 3 , c );
int com3 = s.compare ( 1 , 3 , cs , 3 ,1 );

//string.erase
删除string 中的一个或几个元素。前两个成员函数,返回要被删除的子串的下
一个元素的iterator; 第三个函数,返回删除后的string 的引用。
(1)删除string 中从_First 到_Last 的字符
iterator erase( iterator _First, iterator _Last );
string <char>::iterator s_Iter;
s_Iter = s.erase ( s.begin ( ) + 3 , s.end ( ) - 1 ); // s_Iter=s.end( )
(2) 删除string 中_It 所指的字符
iterator erase( iterator _It );
s_Iter = s.erase ( s.begin ( ) + 5 );
(3) 删除string 中从_Pos(下标)开始的_Count 个字符
string& erase( size_type _Pos = 0, size_type _Count = npos );
str = s.erase ( 6 , 8 ); // str 也是string

//string::substr
返回从_Off(下标)开始的_Count 个字符组成的string
string substr( size_type _Off = 0, size_type _Count = npos ) const;
string s("I love you!"), sub;
sub=s.substr( ); // sub=”I love you!”
sub=s.substr(1); // sub=” love you!”
sub=s.substr(3,4); // sub=”ove ”





//string类的替换函数:  
string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符
string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符
string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c
string &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串s
string &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符
string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串s
string &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符c
string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串




//string类的插入函数: 
string &insert(int p0, const char *s);
string &insert(int p0, const char *s, int n);
string &insert(int p0,const string &s);
string &insert(int p0,const string &s, int pos, int n);
//前4个函数在p0位置插入字符串s中pos开始的前n个字符
string &insert(int p0, int n, char c);//此函数在p0处插入n个字符c
iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置
void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符
void insert(iterator it, int n, char c);//在it处插入n个字符c




//string类的删除函数 
iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串




//string类的迭代器处理: 
string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。
用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
const_iterator begin()const;
iterator begin();                //返回string的起始位置
const_iterator end()const;
iterator end();                    //返回string的最后一个字符后面的位置
const_iterator rbegin()const;
iterator rbegin();                //返回string的最后一个字符的位置
const_iterator rend()const;
iterator rend();                    //返回string第一个字符位置的前面
rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现


 
8>:


9>:


10>:






//==============
C++static成员一定要在类外初始化的原因 :避免重复定义和初始化


#include <iostream>


using namespace std;


class A
{
public:
 int m_a;
 static int m_count; // 注意属性为public
public:
 A(int x):m_a(x){cout<<"A"<<endl;};
 int getData()
 {
  return m_count;
 }
 int get_m_a_data() // 非静态成员函数可以访问静态成员变量
 {
  m_count +=1;
  return m_count;
 }
 static int get_m_count()
 {
  //m_a +=1;    // 静态成员函数没有this指针,不能访问非静态成员变量
  //return m_a; // 同上


  m_count +=1;
  return m_count;
  
 }
};


int A:: m_count=0; // 静态成员变量一定要初始化


int main()
{
 
 cout<<m_count<<endl; // 报错
 cout<<A::m_count<<endl;
 
 return 0;
}


//===========================
//检测文件及文件夹是否存在 权限  函数 access(); _access();


#include <io.h>
功 能: 确定文件或文件夹的访问权限。即,检查某个文件的存取方式,比如说是只读方式、只写方式等。如果指定的存取方式有效,则函数返回0,否则函数返回-1。


用 法: int access(const char *filenpath, int mode); 或者int _access( const char *path, int mode );
参数说明:
filenpath
文件或文件夹的路径,当前目录直接使用文件或文件夹名
备注:当该参数为文件的时候,access函数能使用mode参数所有的值,当该参数为文件夹的时候,access函数值能判断文件夹是否存在。在WIN NT 中,所有的文件夹都有读和写权限
mode
要判断的模式
06     检查读写权限 
04     检查读权限 
02     检查写权限 
01     检查执行权限 
00     检查文件的存在性


access函数程序范例(C语言中)
#include <stdio.h>
#include <io.h>
int file_exists(char *filename);
int main(void)
{
printf("Does NOTEXIST.FIL exist: %s\n",
file_exists("NOTEXISTS.FIL") ? "YES" : "NO");
return 0;
}
int file_exists(char *filename)
{
return (access(filename, 0) == 0);
}


//===========================
“常量”与“只读变量”的区别 解释一些编译报错
 
 下面例子在有的编译器中会报错
const int a = 5;
int b[a];  //报错


 switch(i)
 {
 case a: //报错 :case expression not constant
break;
 //...
 }
 
解释一:
这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5,“abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,"case"后必须是常量 所以“只读变量”也是不可以的。


解释二:
在c/C++中,常量表达式必须是编译期常量,const int i这种东西不是编译期常量(是运行期常量),所以报错


//===========================































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值