1
void main()
{
int a[3];
int* &p=a;
}
为何编译通不过?有何语法错误?为何给指针建立引用就可以?数组名不也是个指针吗?为何给它建立个指针引用就不可以?这是为何请详细解释?
回答:这个问题是属于类型不匹配,a是首地址是常量了,而p是指针变量,变量当然不能对常量引用啦 ,如果把p指针const就可以了
改成 int * const &p=a;
这就可以了
2 int strlen(char *str ){ } 但不允许定义变量 写出函数体 int strlen(int *p) { if (*p) return 1 + strlen(p + 1); else return 0; }
3 对于函数重载,如果区别仅仅在于是否将形参定义为const,这种差异不影响传入至函数的对象,第二个函数声明被视为第一个的重复声明,其原因在于实参传递的方式,复制形参时并没有考虑形参是否为const,函数操纵的只是副本,函数无法修改实参。结果,既可以将const对象传递给const形参,也可以传递非const形参,两者没有区别。 值得注意的是,形参和const形参的等价性仅适用于非引用形参,有const引用形参的函数和有非const引用形参的函数是不同的,类似的,如果函数指向带有const类型引用的指针形参,则与带有指向相同类型的非const对象的指针形参的函数不相同。
如 对于一个类
class screen{
public:
screen &display(std::ostream &os)
{}
const screen &display(std::ostream &os) const
{}
}
这两个函数是不同的,在使用的时候非const对象调用第一个 const对象调用第二个
4 #pragma pack规定的对齐长度,实际使用的规则是:结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
#pragma pack(push)
#pragma pack(8)
struct s2
{
char para1; //虽然 #pragma pack(8)规定按8字节对齐,但是sizeof(char)=1 <8所以还是按1来对其也就是说如果para1的地址为0xffffff00,那么para3的地址为:0xffffff01。para2的地址为:0xffffff01
char para3;
char para2;
};
5 重载操作符必须具有一个类类型的操作数,当为成员函数时,并且this指针指向左操作符。如果将关于iostream的重载设定为成员函数,那么左操作数必须是该对象了,不符合常规
6 重载为类成员的操作符的参数最多只有一个。
7 void f(int b[1])其中b[1]是干什么用的,传的地址吗??
{
int i;
for(i=2;i <6;i++)b[i]*=2;
}
int b[]表示形参是一个int数组,那个1是没有用的 编译系统只会检测参数类型
c++里面如果函数参数传的是数组的话,会将数组转化为指针。
所以下列3种情况是等价的:
1. void f(int* p)
2. void f(int a[])
3. void f(int a[10])
8 关于预定义
@#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
Debug版本,重新定义了 new ,记了一下你程序中 new的文件及代码行数。一旦有内存泄漏,就会在Debug窗口提示你哪个文件哪一行有内存泄漏。
@#if !defined(AFX_PRINTGL_H__DEF59F07_6A94_11D2_8A14_00104B09950B__INCLUDED_)
#define AFX_PRINTGL_H__DEF59F07_6A94_11D2_8A14_00104B09950B__INCLUDED_
其实就是为了防止头文件重复包含用的。
a.h
#ifndef XXX_H//#if !defined就是#ifndef
#define XXX_H
#endif
b.h//include 了a.h
#include "a.h"
c.cpp//include 了a.h和b.h,由于b.hinclude 了a.h ,于是c.pp就include 了两次a.h
#include "a.h"
#include "b.h"
至于AFX_PRINTGL_H__DEF59F07_6A94_11D2_8A14_00104B09950B__INCLUDED_,是VC自动生成的。你也可以自己写写个简单的如XXX_H,但可能会与别人写的冲突。
9 关于scrcmp
int __cdecl strcmp (const char *src, const char *dst)
{
int ret = 0 ;
while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
{
++src;
++dst;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
-------------------------------------------------------------------------------
从下面几个方面阐述:
1.src和dst都为空串如何返回?
2.为什么要用unsigned char*强制转换?
3.可否用*src替换*dst作为while条件?
4.是否是multithread-safe?
5.能否用于multibyte-character strings的比较?
6.能否用更少行表达?
10 unsigned char型8个位顺序翻转
ch = (ch >> 7) | ((ch & (1 < <6)) >> 5) | ((ch & (1 < <5)) >> 3)
| ((ch & (1 < <4)) >> 1) | ((ch & (1 < <3)) < < 1) | ((ch & (1 < <2)) < < 3)
| ((ch & (1 < <1)) < < 5) | (ch < < 7);
11 对象的成员变量初始化动作发生在进入析构函数本体之前
12 class成员变量总是按照其声明的顺序进行初始化
13 如果你定义一个空类,那么编译器会为你声明一个copy构造函数,一个copy assignment 操作符和一个析构函数,以及一个默认的构造函数
copy构造函数 empty(const empty &ths){}
14 为什么用了宏名字定义检测头文件的重复包含可还是有重复定义的错误?
你放在头文件,对于使用文件而言确实未重复包含,但对整个工程而言,每个使用这个头文件的cpp文件编译生成的obj文件中均编译出了这个函数的实体,这样整个工程链接的时候,报信息,重复包含是编译期间的,#ifndef...#define...#endif这个只能解决重复包含,但无法解决重复定义的,重复定义是链接期间的,一个原则:
不分配内存的,放在头文件
分配内存的放在cpp文件,放置重复定义
15 关于operator=防止自我赋值
(1)if(this==&rhs) return *this;
delete pb;
pb=new bitmap(*rhs.pb);//这个具有自我赋值安全性,但是不具备异常安全性,如果这句话抛出异常,那么该类将会持有一个指针指向一个被删除的bitmap,这样的指针有害。
return *this;
(2)bitmap *porig=pb;
pb=new bitmap(*rhs.pb);//这次不怕抛出异常了,你可以把上面防止自我赋值加到这个地方。
delete porig;
return *this;
16 当你编写一个复制函数时,请确保(1)复制所有的local成员变量
(2)调用所有base class内的适当的复制函数。
如
在派生类的复制函数内部,调用基类的赋值操作符 custom::operator=(rhs)
rhs是复制函数参数,是个派生类的对象,这是为了对base class成分进行赋值动作。
17 sizeof()的结果只与类型有关,与值无关
你可以 cout < <sizeof(string);
18 关于cin去除错误标志
应该用cin.clear()清除所有状态,包括bad和fail
另外,还需使用cin.sync()刷新缓冲区
否则,上一次的输入将会影响以后的输入
19vector <vector <int> > array 动态分配方法
1
array.size(10);
for(int i=0;i <10;i++)
array[i].size(20);
2
for(int i=0;i!=10;++i){
vec.push_back(vector <int>(10));
for(int j=0;j!=10;++j){
vec[i][j]=i*j;
}
}
3 int N,M;
vector < <vector <int> > array(N, vector <int>(M));//N行M列,动态的
20
对以“///” 如果是偶数个,正确 结果是其一般个反斜杠,如果是偶数个,错误,会认为最后一个反斜杠和最后的分号看成转义字符
21
## 是连接符。1##2就是12
这是宏定义的。
例如:#define toString(a,b) a##b /*表示把a和b联合成一个符号*/
使用:char *p=toString("1","2") <==> char *p="12";
另外,还有个:#define toString(a) #a /*表示把宏参数a作为字符串*/
使用:char *p=toString(1) <==> char *p="1";
请看另一个例子:
#define PRINT(FORMAT,VALUE) /
printf("The value of "#VALUE" is " FORMAT" /n",VALUE)
调用:PRINT("%d",x+3) (x=22)
输出:The value of x+3 is 25