1)输出当前源文件的文件名以及源文件的当前行号?
解答:
ANSI C标准预定义宏:
1)__LINE__:在源文件中插入当前源代码行号;
2)__FILE__:在源文件中插入当前源文件名;
3)__DATE__:在源文件中插入当前的编译日期;
4)__TIME__:在源文件中插入当前编译时间;
5)__STDC__:当要求程序严格遵循ANSI C标准时该标识符被赋值为1,表明是标准C程序。
实现代码如下:
#include <iostream>
int main()
{
std::cout<<"the file name is : "<<__FILE__<<std::endl;
std::cout<<"the line number is : "<<__LINE__<<std::endl;
std::cout<<"the date is : "<<__DATE__<<std::endl;
std::cout<<"the time is : "<<__TIME__<<std::endl;
#if defined(__cplusplus)
std::cout<<"标准C++程序环境"<<std::endl;
#endif
#if defined(__STDC__)
std::cout<<"标准C程序环境"<<std::endl;
#endif
system("pause");
return 0;
}
2)#pragma once和#ifndef #define…#endif的联系和区别?
解答:
相同点:都能够避免同一个文件被include多次,但#ifndef #define…#endif不只有这个作用,在能够支持这两种方式的编译器上,它们没有太大的区别。
1) #pragma once:
编译器相关的,即不一定在每个编译器上都能用,这得看编译器有没实现它咯!当我们声明#pragma once时,同一文件不会被包含多次,这里指的同一个文件是指物理上的一个文件。但是当某个头文件有多份拷贝时,本声明不能保证它们不被重复包含!
在有的版本的MFC程序中可以看到:
# ifndef XX
# define XX
# if _MSC_VER > 1000
# pragma once
# endif
//
//
# endif
其中,_MSC_VER解析如下:
MS:Microsoft的缩写;
C:MSC指的是Microsoft的C编译器;
VER:Version的缩写;
# if _MSC_VER > 1000指的就是如果编译器版本高于1000(VC++5.0),因此在_MSC_VER小于1000的VC编译器中是不支持#pragma once的。
2) #ifndef #define …#endif
C++语言相关的,这是C++语言的宏定义,通过该宏定义来避免文件被多次包含。它在所有支持C++语言的编译器上都是有效的。
#ifndef...是由语言支持的,它依赖于宏名字不能冲突,因此,不仅可以保证同一个文件不会被包含多次,也可以保证内容完全相同的两个文件不会被同时包含。为了保证不同头文件中的宏名不冲突,一般采取类似于_ASCE_H_的命名方式,如头文件asce.h开头一般定义如下:
#ifndef __ASCE_H_
#define __ASCE_H_
//一些声明的语句
#endif
3) 两者的对比:
性能上的区别:使用#ifndef,编译器每次看到#include这个文件时都有读入该文件,并解析代码;而使用#pragma once时编译器根本不会重复打开头文件,大大提高了效率;
编码风格上的区别:使用#pragma once代码简洁,且避免了头文件宏名的重定义,以及#endif包含范围的错误等情况;
语意上的区别:#pragma once是针对文件,它告诉编译器本文件只编译一次;#ifndef #define …#endif只是针对文件中的某一个标号而言,它能防止三个指令间包含的内容的重复性处理,因此,后者比前者更灵活;
可移植性的区别:#pragma once是微软的开发工具中引入的;#ifndef #define…#endif是C++标准里面的一部分,因此后者比前者移植性更好;
3)程序和算法有何不同?
解答:程序是算法用某种程序设计语言的具体实现,程序可以不满足算法的性质之一:有限性;例如操作系统是一个在无限循环中执行的程序,因而不是一个算法。然而,我们可以把操作系统的各种任务看成是一些单独的问题,每一个问题由操作系统的一个子程序通过特定的算法来实现。
4)算法渐近分析中Ο、Ω、Θ分别表示什么?
解答:对于任何数学函数f(n),Ο、Ω、Θ这三个记号用来度量其“渐近表现”,即当n趋向于无穷大时f(n)的阶的情况,我们可以将它们分别想象成≤、≥和=,分别估计了函数的渐近上界、渐近下界和准确界。
5)C++子类名称覆盖问题?
解答:子类若定义了与基类成员名称相同的成员,则基类成员在子类中会被覆盖掉;C++的名称覆盖规则很简单:只看名称,不区别类型。
如果基类中存在某个成员函数的若干个重载版本,而子类也定义了同名函数(参数类型和返回值是否一致不重要),则基类中所有版本的重载函数在子类中都会被覆盖掉。