C++备忘知识整理

一、设置字体颜色

C++控制台程序运行时输出框默认的文字颜色是白色,所以我常称其输出框为黑白框。但是这个文字样式不是固定不变的,是可以改变颜色的字体的。方法有两种:

1、设置输出框的框体属性。在运行时弹出的输出框标题栏上点击右键设置它的属性,可以调节输出框的大小、背景色、文字颜色等属性。但是这种设置只能在自己的机子上运行显示。在其他人的机子上是没有用的。这里不做重点介绍。

2、用代码修改。这里介绍C++中用代码修改输出框显示文字的颜色。具体代码是调用一个函数SetConsoleTextAttribute(参数表)。

SetConsoleTextAttribute()函数是一个API设置字体颜色和背景色的函数。参数表中使用两个属性(属性之间用,隔开)。GetStdHandle()和FOREGROUND_*或BACKGROUND_*。*值为INTENSITY或RED或GREEN或BLUE。第一个属性获得句柄(即要设置颜色的地方),第二个属性设置颜色。属性相加是在属性值中间加“|”隔开即可。

GetStdHandle(STD_OUTPUT_HANDLE)获得句柄。

FOREGROUND_INTENSITY  表示设置前景色为高亮显示。

FOREGROUND_RED        表示设置前景色为红色,即字体颜色为红色。

FOREGROUND_GREEN      表示设置前景色为绿色,即字体颜色为绿色。

FOREGROUND_BLUE       表示设置前景色为蓝色,即字体颜色为蓝色。

BACKGROUND_INTENSITY  表示设置背景色为高亮显示。

BACKGROUND_RED        表示设置背景色为红色。

BACKGROUND_GREEN      表示设置背景色为绿色。

BACKGROUND_BLUE       表示设置背景色为蓝色。

……      ……      ……      ……      ……      ……

说明:在使用时要在预处理中包含window.h头文件

举例如下:

#include

#include"windows.h"

using namespace std;

void main()

{

cout<<"原色testCOLOR(没有设置字体颜色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|

                        FOREGROUND_GREEN|FOREGROUND_BLUE);//设置三色相加

cout<<"白色testCOLOR(红色绿色蓝色相加)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);

                       //设置红色

cout<<"红色testCOLOR(设置的颜色为红色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN)

                       ;//设置绿色

cout<<"绿色testCOLOR(设置的颜色为绿色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);

                       //设置蓝色

cout<<"蓝色testCOLOR(设置的颜色为蓝色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|

                       FOREGROUND_GREEN);//设置红色和绿色相加

cout<<"黄色testCOLOR(红色和绿色相加色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|

                       FOREGROUND_BLUE);//设置红色和蓝色相加

cout<<"粉色testCOLOR(红色和蓝色相加色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|

                       FOREGROUND_BLUE);//设置绿色和蓝色相加

cout<<"青色testCOLOR(绿色和蓝色相加色)"<<endl;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);

                       //设置颜色,没有添加颜色,故为原色

cout<<endl;

}

 


 

 二、C++中内存模型的几种存储说明符

关键字提供的存储说明符有auto , register, static ,extern,mutable,C-V限定符有const和volatile.

 

1.auto用在将变量声明为自动变量,就是留出一段内存,成为堆栈,以管理变量的增减,这个过程是自动完成的.

 

2.register关键字用来声明局部变量.寄存器变量是存储持续性为自动的,能提供对变量的快速访问,但是分配空间与回收都取决与CPU.如果该变量被频繁使用,就请声明为register变量.

 

3.static 静态变量.未被初始化的静态变量一般都被设置成0,只能用常量表达式来初始化静态变量.可以使用const常量和enum常量以及sizeof操作符,static变量将被分一块独立的内存空间.

 

4.extern 重新定义以前定义过的外部变量,该变量将自动隐藏定义过的外部变量.

 

5.const 表明程序对他进行初始化以后,便不能再被修改了.

 

6.volatile .即使程序代码没有对内存但愿进行修改,其值也可能发生变化.

 

7.mutable 即使结构或者类变量为const.其某个成员也可以被修改。


 

 三、函数指针与指针函数

指针函数函数指针的区别:
1,这两个概念都是简称,指针函数是指返回值是指针的函数,即本质是一个函数。我们知道函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。
其定义格式如下所示:
返回类型标识符*函数名称(形式参数表)
{函数体}
返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整形值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子:
//指针函数是指返回值是指针的函数,即本质是一个函数:
#include<iostream>
using namespace std;
int main()
{
  float*find(float(*p)[4],intm);//查询序号为m的学生的四门课程的成绩
  float score[][4]={{50,51,52,55},{70,70,40,80},       {77,99,88,67}};//定义成绩数组,第一维可以为变量
  float*pf=NULL;//定义一个指针时一定要初始化
  int i,m;
  cout<<"请输入您想查询的学生的序号:";
  cin>>m; 
  pf=find(score,m);//返回为一维数组指针,指向一个学生成绩
  for(i=0;i<4;i++)
  cout<<*(pf+i)<<"";
  cout<<endl;
  return 0;
}
float *find(float(*p)[4],intm)
{
  float *pf=NULL;
  pf=*(p+m);//p是指向二维数组的指针,加*取一维数组的指针
  return pf;
}

      学生学号从0号算起,函数find()被定义为指针函数,其形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向 score的第一行。*(pointer+1)指向第一行的第0个元素。pf是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.

这两个名字不同当然所代表的意思也就不同。我刚开始看到这就吓到了,主要是中文太博大精深了,整这样的简称太专业了,把人都绕晕了。从英文解释或中文全称看就比较容易理解。

四、数组指针与指针数组

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

还要注意的是他们用法的区别,下面举例说明。

int* a[4]     指针数组     

                 表示:数组a中的元素都为int型指针    

                 元素表示:*a[i]   *(a[i])是一样的,因为[]优先级高于*

int (*a)[4]   数组指针     

                 表示:指向数组a的指针

                 元素表示:(*a)[i]  

注意:在实际应用中,对于指针数组,我们经常这样使用:

typedef int* pInt;
pInt a[4];
#include <iostream>
 
using namespace std;
 
int main()
{
int c[4]={1,2,3,4};
int *a[4]; //指针数组
int (*b)[4]; //数组指针
b=&c;
//将数组c中元素赋给数组a
for(int i=0;i<4;i++)
{
a[i]=&c[i];
}
//输出看下结果
cout<<*a[1]<<endl; //输出2就对
cout<<(*b)[2]<<endl; //输出3就对
return 0;
}

注意:定义了数组指针,该指针指向这个数组的首地址,必须给指针指定一个地址,容易犯的错得就是,不给b地址,直接用(*b)[i]=c[i]给数组b中元素赋值,这时数组指针不知道指向哪里,调试时可能没错,但运行时肯定出现问题,使用指针时要注意这个问题。但为什么a就不用给他地址呢,a的元素是指针,实际上for循环内已经给数组a中元素指定地址了。但若在for循环内写*a[i]=c[i],这同样会出问题。总之一句话,定义了指针一定要知道指针指向哪里,不然要悲剧。

五、几种容器比较

顺序容器:

1.vcetor 

vector类型适用于需要随机访问元素的情况,支持下标操作,无push_front()操作。
2.deque
deque类型适用于需要在容器的尾部或首部插入和删除元素的情况,支持下标操作。
3.list
list类型适用于需要在容器的中间位置插入和删除元素的情况,不支持下标操作。
关联容器:
4.map
map类型适用于需要键-值对的集合的情况。
5set
set类型适用于需要使用键集合的情况。
关于顺序容器的选用:
1.通常来说,除非找到选择使用其他容器的更好理由,否则vector容器都是最佳选择。
2.如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑在输入时将元素读到一个list容器中,接着对此容器重新排序,使其适合顺序访问,然后将排序后的list容器复制到一个vector容器中。
3.如果无法确定某种应用应该采用哪种容器,则编写代码时尝试只使用vector和list容器都提供的操作:使用迭代器,而不是下标,并且避免随机访问元素,这样编写代码,在必要时,可很方便地将程序从使用vector容器修改为使用list容器。

六、C++几种类型转换

1、const_cast 通常被用来将对象的常量性转除(cast away the constness),它也是唯一有此能力的C++-style转型操作符。
2、dynamic_cast主要用来执行“安全向下转型”(safe downcasting),也就是用来决定某对象是否归属继承体系中的某个类型。他是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
3、reinterpret_cast意图执行低级转型,实际动作(及结果)可能取决于编译器,这也就表示它不可移植,例如将一个指向int类型的指针转型为int,这一类转型在低级代码以外很少见。
4、static_cast用来强迫式隐式转换(implicit conversions),例如将non-const对象转为const对象,或将int转为double等等,也可以用来执行上述多种转换的反向转换,例如将void*指针转为type指针,将指向基类的指针转为指向派生类的指针,但它无法将const转为non-const——这只有const_cast才办得到。
posted @ 2015-01-10 20:08  Rimond_Jing  阅读(453)  评论(0编辑  收藏  举报