标签:
C是结构化语言,重点在于算法和数据结构。C程序的设计首先考虑的是如何通过过程,对输入进行运算处理得到输出。对于C++,首先考虑如何构建对象模型,让模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程控制。
阻止该头文件被重复引用。
C++支持函数重载,而C语言不支持函数重载。函数被C++编译后在库中的名字与C语言有所不同。假设函数原型为 void foo(int i,int j)
,则C语言编译后在库中的名字为_foo
,而在C++编译后的库中名字为_foo_int_int
的名字。C++提供了连接交换指定符号extern“C”
解决名字匹配问题。
malloc与free是C/C++语言的标准函数库,new/delete是C++运算符。他们都可以动态申请和释放内存。对于非内部数据类型的对象,只用malloc无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡前自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
指针函数:指针函数是带指针的函数,即本质是一个函数。函数返回类型是某一类型指针。函数返回值必须用同类型的指针变量来接受。指针函数一定有函数返回值,而且在主调函数中,函数返回值必须赋给同类型的指针变量。
类型标识符 *函数名(参数表)//int* f(int x,int y)
示例
int * GetDate(int wk,int dy);
main()
{
int wk,dy;
do
{
printf(Enter week(1-5)day(1-7)\n);
scanf(%d%d,&wk,&dy);
}
while(wk<1||wk>5||dy<1||dy>7);
printf(%d\n,*GetDate(wk,dy));
}
int * GetDate(int wk,int dy)
{
static int calendar[5][7]=
{
{1,2,3,4,5,6,7},
{8,9,10,11,12,13,14},
{15,16,17,18,19,20,21},
{22,23,24,25,26,27,28},
{29,30,31,-1}
};
return &calendar[wk-1][dy-1];
}
函数指针:函数指针是指向函数的指针变量,即本质是一个指针变量。
类型标识符 (*函数名)(参数表)//int (*f)(int x,int y)
指向函数的指针包含了函数的地址,可以通过它来调用函数。把函数地址赋值给指针,可以采用下面两种形式:
void (*fptr)();
fptr=&Function;
fptr=Function;
取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。可以采用如下两种方式来通过指针调用函数:
x=(*fptr)();
x=fptr();
示例
void (*funcp)();
void FileFunc(),EditFunc();
main()
{
funcp=FileFunc;
(*funcp)();
funcp=EditFunc;
(*funcp)();
}
void FileFunc()
{
printf(FileFunc\n);
}
void EditFunc()
{
printf(EditFunc\n);
}
程序输出为:
FileFunc
EditFunc
参考来源:http://www.cnblogs.com/gmh915/archive/2010/06/11/1756067.html
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
pointer=*P++
等价于pointer=*P;P++;
pointer=*++P
等价于P++;pointer=*P;
float value[] = {1,2,3,4,5};
float *vp;
vp = value;
for (int i = 0; i < 5;++i)
cout << *vp++ << ", ";
程序的输出结果为1,2,3,4,5,若修改为*++vp
,则结果为2, 3, 4, 5, -1.07374e+008
数组a[]的内存分配在栈上,可以通过数组名或指向数组的指针进行修改。而下面的指针p指向的是文字常量区的字符串,是不允许修改的,故通过指针修改错误。但是可以使用p[0]访问相应的元素。
char a[]="hello";
a[0]=‘x‘;
char* q=a;
q[0]=‘b‘;
char *p="hello";//将字符串的首地址装入指针变量,而不是将整个字符装入指针变量
p[0]=‘x‘;
指针数组: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];
参考来源:http://www.cnblogs.com/Romi/archive/2012/01/10/2317898.html
事实上,C++没有提供高维数组内省。以二维数组(int a[4][5])为例,用户创建的二维数组其实是每个元素本身都是数组的数组。
int(*)[5]
,即a
为指向数组a第0个元素a[0]的指针,且a为常量,不可进行赋值运算,a+i
的类型也同为int(*)[5]
,指向a[i]; &a+1如图中所示,跳过4行5列共20个元素。int*
,a为指向数组a[0]*首元素a[0][0]的指针。int*
,因a的类型为int(*)[5],即a指向一个有5个元素的一维数组,故a+1跳过5个元素。即 *(a+1)或a[1]为指向数组a[1]首元素a[1][0]的指针。int
。(*(a+1)+2)为指向数组a[1]第二个元素a[1][2]的指针,即为数组a[1]
的第2个元素a[1][2]
。总结:
在下面的程序片段中
int a[]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
cout<<*(ptr-1);//结果为5
由于&a+1的类型是int(*)[5],不是a+1。故&a+1使得指针跳过整个数组a的大小(5个int的大小)。ptr经过强制转换实际是&(a[5]),即a+5,所以ptr-1指向数组a的最后一个元素。输出结果为5。
static关键字作用 - 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只能被分配一次,因此其值在下次调用时仍维持上次的值。 - 在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问。 - 在模块内的static函数只能被该模块内的其他函数调用,这个函数的使用范围被限制在它申明的模块内。 - 在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝。 - 在类中的static成员函数属于整个类所有,该函数不接收this指针,因而只能访问类的static成员变量。
面向对象设计的三原则:封装、继承、多态
虚函数在vtable中占了一个表项,保存着一条跳转到它的入口地址的指令。当一个包含虚函数的对象被创建时,它的头部附加一个指针,指向vtable中相应的位置。调用虚函数的时候,不管用什么指针调用,根据vtable找到入口地址再执行,从而实现“动态联编”。而不像普通函数那样简单地跳转到一个固定地址。
友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元的作用在于提高程序的运行效率,但是它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
虚拟继承是为解决多重继承而出现的。
虚指针或虚函数指针是一个虚函数的实现细节。带有虚函数的类中的每一个对象都有一个虚指针指向该类的虚函数表。
标签:
原文地址:http://www.cnblogs.com/ucas/p/5347047.html