有关C/C++的一些基础知识

1.多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?

答案:虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键.


2.一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态?在子类的空间里,有没有父类的这个函数,或者父类的私有变量?

答案:只要基类在定义成员函数时已经声明了virtue关键字,在派生类实现的时候覆盖该函数时,virtue关键字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外)


3.完成字符串拷贝可以使用 sprintf、strcpy 及 memcpy 函数,请问这些函数有什么区别

答案:这些函数的区别在于 实现功能 以及 操作对象 不同。
1.strcpy 函数操作的对象是 字符串,完成 从 源字符串目的字符串拷贝 功能。
2.sprintf 函数操作的对象不限于字符串:虽然目的对象是字符串,但是源对象可以是字符串、也可以是任意基本类型的数据。这个函数主要用来实现(字符串或基本数据类型)向字符串的转换功能。如果源对象是字符串,并且指定 %s 格式符,也可实现字符串拷贝功能。
3.memcpy 函数顾名思义就是 内存拷贝,实现 将一个 内存块 的内容复制到另一个 内存块 这一功能。内存块由其首地址以及长度确定。程序中出现的实体对象,不论是什么类型,其最终表现就是在内存中占据一席之地(一个内存区间或块)。因此,memcpy 的操作对象不局限于某一类数据类型,或者说可适用于任意数据类型,只要能给出对象的起始地址和内存长度信息、并且对象具有可操作性即可。鉴于 memcpy 函数等长拷贝的特点以及数据类型代表的物理意义,memcpy 函数通常限于同种类型数据或对象之间的拷贝,其中当然也包括字符串拷贝以及基本数据类型的拷贝。

对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同:

  • strcpy 无疑是最合适的选择:效率高且调用方便。
  • snprintf 要额外指定格式符并且进行格式转化,麻烦且效率不高。
  • memcpy 虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如果长度指定过大的话(最优长度是源字符串长度 + 1),还会带来性能的下降。其实 strcpy 函数一般是在内部调用 memcpy函数或者用汇编直接实现的,以达到高效的目的。因此,使用 memcpy 和 strcpy 拷贝字符串在性能上应该没有什么大的差别。

对于非字符串类型的数据的复制来说,strcpy 和 snprintf 一般就无能为力了,可是对 memcpy 却没有什么影响。但是,对于基本数据类型来说,尽管可以用 memcpy 进行拷贝,由于有赋值运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,所以这种情况下 memcpy 几乎不被使用。memcpy 的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其目的是或者高效,或者使用方便,甚或两者兼有。


4.变量的声明和定义有什么区别

声明是向编译器介绍名字--标识符。它告诉编译器“这个函数或变量在某处可找到,它的模样象什么”。而定义是说:“在这里建立变量”或“在这里建立函数”。它为名字分配存储空间。无论定义的是函数还是变量,编译器都要为它们在定义点分配存储空间。对于变量,编译器确定变量的大小,然后在内存中开辟空间来保存其数据,对于函数,编译器会生成代码,这些代码最终也要占用一定的内存。  

  在C和C++中,可以在不同的地方声明相同的变量和函数,但只能有一个定义(有时这称为ODR,单一定义规则)。。。  

  定义也可以是声明,如果有int   x;,之前编译器未发现标识符x,编译器则把这一标识符看成是定义并立即为它分配存储空间。  

  。。。。。  

  对“变量声明”的解释向来模糊且自相矛盾。。

  函数声明包括函数类型、函数名、参数列表和一个分号,这些信息足以编译器认出它是一个函数声明并可识别出这个函数的外部特征。由此推断,变量声明应是类型标识后面跟一个标识符。如int   a;但这产生了一个矛盾,这段代码有足够的信息让编译器为之分配存储空间,而且编译器也确实给之分配了存储空间。要解决这个问题,对于C和C++需要一个关键字来说明“这是一个声明,它的定义在别的地方”,这个关键字就是extern,它表示变量是在文件以外定义的,或在文件后面定义的。  

  在变量定义前加extern表示声明一个变量但不定义它,如:  

 extern   int   a;  

 extern也可用于函数声明,如:  

 extern   int   func1(int  length,int   width);  

  但由于没有函数体,编译器必把它当成声明而非定义,extern对于函数来说是多余的、可选的。C语言的设计者并不要求函数声明使用extern,这可能有些令人遗憾,如果函数声明也要求用extern,那么形式上与变量声明更加一致了,从而减少了混乱(但这就需要更多的输入,这也许能解释为什么不要求函数声明使用extern的原因)。


5.字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?为什么?

答案:指针变量也占用内存单元,而且所有指针变量占用内存单元的数量都是相同的。就是说,不管是指向何种对象的指针变量,它们占用内存的字节数都是一样的,并且要足够把程序中所能用到的最大地址表示出来(通常是一个机器字长)。

6.同步机制应该遵循哪些基本准则?

1.空闲让进 2.忙则等待3.有限等待4.让权等待


7.各种类型32位或者64位的编译器下所占用的字节数

32位编译器
char 1个字节
char*
(即指针变量): 4个字节(32位的寻址空间是2^32,32bit,也就是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
个字节

8.

char * GetStr()
{
    char *tmp;
    tmp = "123"
    return tmp;
}
void main()
{
    printf("%s", GetStr());
}
会输出123吗?123创建在堆上还是栈上呢?123的空间是什么时候释放的?
会, "123"  是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈   在程序结束时自动释放

9.应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?

参考:对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量

10.用<<,>>,|,&实现一个WORD(2个字节)的高低位交换!!

int  main() 
{ 
	unsigned  short  a  =  0xABCD; 
	unsigned  short  b  ; 
	unsigned  short  c  ,d; 
	b  =  (a  <<  8)&0xff00;   
	c  =  (a  >>  8)&0x00ff; 
	d  =  b  |  c; 
	printf("\n%x",a);
	printf("\n%x",b); 
	printf("\n%x",c); 
	printf("\n%x\n",d); 
	return  0; 
}
结果是  CDAB   
2俩个字节是16位  前八位为高位  后八位为低位  然后结合

11.写出运行结果

int sum(int a)
{ auto int c=0;		//自动变量,值都会初始化
  static int b=3;	//静态变量,值不会初始化
c+=1;
b+=2;
return(a+b+c);
}
void main()
{ int i;
int a=2;
for(i=0;i<5;i++)
{ printf("%d,", sum(a));}
}
8,10,12,14,16

12.

9:某进程在运行过程中需要等待从磁盘上读入数据,此时进程的状态将:C

A: 从就绪变为运行  B:从运行变为就绪

C: 从运行变为阻塞  D:从阻塞变为就绪

解析:
  • 运行状态(Running):进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
  • 就绪状态(Ready):进程已获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器进程就可执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排人低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列
  • 阻塞状态(Blocked):当进程由于等待I/O操作或进程同步等条件而暂停运行时,它处于阻塞状态

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值