C++知识点、考点。--很好

来源:互联网 发布:dnf如果合约到期知乎 编辑:程序博客网 时间:2024/06/05 21:05

网站:http://www.cnblogs.com/lca1826/p/6502130.html

http://blog.csdn.net/lina_acm/article/details/51603061

http://www.cnblogs.com/SeekHit/p/5707343.html

1、标准头文件的一些通用结构的理解:P32

#ifndef Biaotih#define Biaotih#ifdef __cplusplusextern "C"{#endif#include <stdio.h>#ifdef __cplusplus}#endif#endif
其中#ifndef Biaotih是为了防止头文件被重复的引用,第三行的是表示当前使用的是C++编译器,还是C编译器。

其中的extern "C"的作用有双重含义:首先,它使用extern,告诉编译器,其声明的函数和变量可以在本模块或其他模块使用。"C"的作用是是告诉编译器其是按C语言方式编译和链接的。其中C++支持函数重载,而C语言不支持。函数被C++编译后再符号库中的名字与C语言的不同,例如下面两个函数:

void foo(int x, int y);void foo(int x, float y);
两者在c++里的符号库是不同的,其分别为_foo_int_int、_foo_int_float。而c里的可能就是_foo。c++就是靠这种机制重载的,而c中链接c++编译的时候就会出现因找不到符号问题发生链接错误。

2、define P38

#define SOR(x) (x*x)        int a, b = 3;a = SOR(b + 2);printf("a=%d\n", a);
其输出结果是11.本来是要25的。原因是define是在预处理的时候进行了文本的替换,其被替换成为:a=(b+2*b+2).为达到目的,可以把SQR(x)改为如下定义:
#define SOR(x) ((x)*(x))

3、C++类的static静态成员

static数据成员定义:1、一般情况下,static数据成员是类内声明,类外定义;2、static成员不通过类构造函数初始化,而是在定义时进行初始化;3、一个例外:初始化式为常量表达式,整型static const 数据成员(static const int) 可以在类的定义体内进行初始化:class Lunais{static const int zty = 30;}

b可以在类外进行初始化,且所有对象共享一个b的值:
int circle::b = 2;
class widget{public:widget();~widget();static int num(){return count;}private:static int count;};widget::widget(){count++;}int widget::count = 0;void main(){widget x, y;cout << "the Num is" << widget::num() << endl;if (widget::num() > 1){widget x, y, z;cout << "the Num.is" << widget::num() << endl;}widget z;cout << "the Num.is" << widget::num() << endl;}
静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。
4、使用sizeof函数来进行求变量字节数

//使用sizeof来计算普通变量所占的空间大小
void Func(char str[100]){
printf("strofFunc:%d\n",sizeof(str));
}
 char str[] = "HELLO";//字符串需要有一个存储字符串结束符,所以为6char *p1 = str; //这里的p1是指针,在win平台上指针分int都是4字节的变量。int n1 = 10;printf("str:%d,p:%d,n:%d\n",sizeof(str),sizeof(p1),sizeof(n1));Func(str); //在调用函数Func(str)时,由于数组是“传址”的,程序会在栈上分配一个四字节的指针来指向数组。结果也是4.
其结果为:

对于类对象的大小:其要注意win有个数据存储对齐其规律为:
常用类型的对齐方式

类型 对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
char 偏移量必须为sizeof(char)即1的倍数
int 偏移量必须为sizeof(int)即4的倍数

long 型是4字节,

long long是8字节
double 偏移量必须为sizeof(double)即8的倍数
short 偏移量必须为sizeof(short)即2的倍数
float 偏移量必须为sizeof(float)即4的倍数


所以:
#include <iostream>
 
using namespace std;
struct MyStruct
{
    double doub;
    char ch;
    int i;
};
 
int main()
{
    MyStruct ms;
    cout << sizeof(ms) << endl;
 
    return 0;
}
答案为16;


对于含有虚函数的类,其是含有隐含的虚表指针成员,其占4个字节。
3、sizeof与strlen的区别:P61
//计算字符串数组的长度,如果要计算指针指向的字符串的长度,则一定要用strlen ,即*ss。
char str[20] = "0123456789";
int a = strlen(str); //结果是10,不计算结束符
int b = sizeof(str); //结果是20
char *ss = "0123456789";
int a2= sizeof(ss); //结果是4,计算的是指针的大小
int b2 = strlen(ss); //结果是10.
4、inline内联函数的好处和引入原因。P62
1、因为其没有了参数压栈,出栈、代码生成等一系列的操作,没有了调用的开销,所以效率很高。
2、其在调用一个内联函数的时候,首先会检查他的参数类型,保证调用正确;然后进行一系列的相关检查,消除了它的隐患和局限性。
3、内联函数在C++类中应用最广的,应该是定义存取函数。我们定义的类中一般会把数据定义成私有的或者保护的,这样外界就不能直接读取这些成员,而是要通过接口函数来读取,如果我们把这些接口函数定义为内联函数的话,将会获得更好的效率。其中在类里面定义的函数就是内联函数,而这类体外定义的函数要加上inline才能是内联函数。如下:
class A1
{
public:
A1();
~A1();
int readTest(){
return nTest;
}
void setTest(int i);
private:
int nTest;
};
inline void A1::setTest(int i)
{
nTest = i;
}


A1::A1() //一般类的构造函数和析够函数不要定义为内联函数。
{
}


A1::~A1()
{
}
为什么不把所有代码定义为内联函数:
1、因为这样的话会导致代码膨胀,使的内存消耗较高。
Adefine与内联函数的区别:
内联函数在编译时展开,而宏定义在预编译时展开。
内联函数有类型检查、语句是否正确等编译功能,而宏没有。
宏不是函数,而inline是函数。
5、&引用  P69

7.什么是“引用”?申明和使用“引用”要注意哪些问题?

引用就是某个目标变量的“别名”,对应用的操作与变量直接操作效果完全相同。声明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因为该引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。

//&引用
int a = 20;
int &b = a; //此时声明b为变量a的一个引用
b = 200;  //此时对b的修改就是对a的一个修改
int equal = (&a == &b)?1:0; //结果是1。
注意:引用类型的变量在声明的时候必须初始化,否则会出错。如下 int &h;则会出错。
其中swap字符串交换函数就是利用指针引用来实现的。
//&指针引用
int a = 1;
int *p = &a; //改p指向的内容也改变了a的内容
int*&pa = p;//改变pa的内容也改变了a的内容。
(*pa)++;
为什么传应用比传指针安全?
  答:因为由于不存在空引用,并且引用一旦被初始化为指向一个对象,他就不能再指向另一个对象的引用,否则会报错,因此引用很安全。而对于指针来说,它随时可以指向别的对象,并且可能为野指针。

13.重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?

从定义上来说:

重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

重写:是指子类重新定义父类虚函数的方法。

不同系统里的类型的字节数是不同的:一般的笔试题都是指32位下的。

       32位      64位 
char      1       1 
int       4      大多数4,少数8 
long      4       8 
float     4       4 
double    8       8 
指针      4       8

20.简述数组与指针的区别?

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。

(1)修改内容上的差别

1 char a[] = "hello";2 a[0] = 'X';3 char *p = "world"; // 注意p 指向常量字符串4 p[0] = 'X'; // 编译器不能发现该错误,运行时错误

(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

复制代码
 1 char a[] = "hello world"; 2 char *p = a; 3  4 //计算数组和指针的内存容量 5 cout<< sizeof(a) << endl; // 12 字节 6 cout<< sizeof(p) << endl; // 4 字节 7  8 //数组作为函数参数传递 9 void Func(char a[100])10 {11     cout<< sizeof(a) << endl; // 4 字节而不是100 字节12 }
复制代码

0 0