程序员面试宝典
一:宏定义
面试例题1:
如何用一个宏定义FIND求一个结构体CTYPE里某个变量CNUM相对了CTYPE的编移量 ?
如:
stuct student { int a; char b[20]; double ccc; } |
则:
FIND(student,a); //等于0
FIND(student,b); //等于4
Answer:
#define FIND(struc, e) (size_t)&(((struc*)0)->e)
(struc*)0 //表示将常量0强制转化为struc *型指针所指向的地址
&(((struc*)0)->e) /*表示取结构体指针(struc*)0的成员e的地址,因为该结构体的首地址为0,
所以其实就是得到了成员e距离结构体首地址的偏移量.*/
(size_t) //是一种数据类型,为了便于不同系统之间移植而定义的一种无符号型数据,
一般为unsigned int*/
(struc*)0 // 表示假设在0地址处有一个结构体struc
((struc*)0)->e // 表示在0地址处的结构体struc的成员e
&(((struc*)0)->e) // 表示在0地址处的结构体struc的成员e 的地址
(size_t)&(((struc*)0)->e) //将0地址处的结构体struc的成员e 的地址转换成整数类型
二:const
1: What does the keyword "const" means in C program ? Please at least make
two examples about the usage of const.
parse:在C程序中,const的用法主要有定义常量、修饰函数参数、修饰函数返回值等3个用处。
在C++程序中,它还可以修饰函数的定义体,定义类中某个成员函数为恒态函数,即不改
变类中的数据成员。
Answer:
(1)可以定义const常量。
(2)const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强
制保护,可以预防意外的变动,能提高程序的健壮性。
2:const 与 #define相比有什么不同 ?
C++语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点.
Answer:
(1)const常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行安全检查,而对后者
只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应).
(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试.在C++程序
中只使用const常量而不使用宏常量,即const常量完全取代宏常量.
相关知识,点击链接: C++中的常量
3:在下述情况下,如果要修改类的成员变量,应该怎么办?
class A_class { void f() const { } } |
Answer:
在const成员函数中,用mutable修饰成员变量名后,就可以修改类的成员变量了。
Sample :
#include <stdio.h> class C { private : mutable int m_Count; public : C( int i):m_Count(i) {} int add() const { return ++m_Count; } int minus() const { return --m_Count; } int print() { printf ( "m_Count = %d\n" , m_Count); } }; int main() { C tmp(5); printf ( "Before add: " ); tmp.print(); tmp.add(); printf ( "After add : " ); tmp.print(); puts ( "" ); printf ( "Before minus: " ); tmp.print(); tmp.minus(); printf ( "After minus : " ); tmp.print(); return 0; } |
三: sizeof
1:What is the output of the following code ?
#include <stdio.h> struct Node1 { char a3; int a1; short a2; }; struct Node2 { int a1; char a3; short a2; }; int main() { printf ( "%d\n" , sizeof (Node1)); printf ( "%d\n" , sizeof (Node2)); return 0; } |
Answer:
结构体对齐:以结构体里最长的数据单元为对齐单元。
所以结构体的长度是最长的数据元素的整数倍。
sizeof (Node1); | char |---|---|---| |------- int ------| |-- short -|-------| sizeof (Node2); |------- int ------| | char |---|- short -| |
12 8
相关知识,点击链接:sizeof(结构体)和内存对齐
2:sizeof() 和 strlen() 的区别?
相关知识,点击链接:sizeof和 strlen 的区别
3:下面程序输出什么?
#include <stdio.h> int main() { int a = 4; printf ( "%d\n" , sizeof (a = 6)); printf ( "%d\n" , a); return 0; } |
Answer:
sizeof不是函数,也不是一元运算符,它是类似宏定义的特殊关键字,sizeof()括号内
的内容在编译过程中是不被编译的,而是被替代类型,如int = 8; sizeof(a)。在编译
过程中不管a是什么值,只是被替代成类型sizeof(int),结过为4。如果是sizeof(a = 6)
呢?也一样是转换成sizeof(int),但需要注意的是:a = 6是不被编译的,所以执行完后,
a的值不变。
4 4
4:下面代码的输出结果是什么?
#include <stdio.h> char var[10]; int test( char var[]) { return sizeof (var); } int main() { printf ( "%d\n" , test( "hello world" )); return 0; } |
Answer:
C/C++传递数组永远是传递数组的首地址,是一个指针。
即int test(char var[]);等价于int test(char var *);等价于int test(char var[8]);
只要是指针类型,sizeof的大小就是4。
4
5:一个空类的空间占多少? 多重继承的空类呢?
Answer:一个空类所占的空间为1,多重继承的空类所占的空间仍然为1。
Sample:
#include <iostream> using namespace std; class A {}; class A1 {}; class B : public A {}; class C : public virtual B {}; class D : public A, public A1 {}; int main() { cout << sizeof (A) << endl; //空类,为了实例化对象的需要,预留一个空间。 cout << sizeof (B) << endl; cout << sizeof (C) << endl; //虚继承涉及到虚表(虚指针),所以sizeof(C)的大小为4 cout << sizeof (D) << endl; return 0; } |
6:内联函数与宏定义的差别是什么?
相关知识,点击链接:内联函数与宏