C++初始化class的时候,大括号和数学小括号中括号大括号有什么区别?

本文介绍了c++中自定义的类怎么使用大括号进行赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

有没有办法实现如下样子的赋值?

使用参数为std::initializer_list的构造函数和/或赋值运算符,任意类都可以使用这个方法。例如:

// 没有考虑各种边界问题,仅为示意

类满足 的条件,则自动可以使用大括号列表来初始化类的成员。

  • 没有定义任何构造函数(但可以使用= default= delete

  • 没有类内初始化(C++14后废除)

所以,题主的类肯定不符合这个条件。

这篇关于c++中自定义的类怎么使用大括号进行赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

犹豫了一下,不知道该不该发这么多。毕竟题目虽全,但是其实很多人看了不到一半,估计就会默默的收藏保存,等待下次再看。

相比与技术的内容,时间和学习效率也是很重要的。如何规划也是我们需要思考的问题。

体系架构。众所周知.NET体系不同于COM体系,接口也就完全不同于ADO和OLE DB接口,这也就是说和ADO是两种数据访问方式。提供对XML的支持。

答案:当类中含有const、reference成员变量,基类的构造函数都需要初始化表。

26. C++是不是类型安全的?

答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。

27. main 函数执行以前,还会执行什么代码?

答案:全局对象的构造函数会在main 函数之前执行。

28. 描述内存分配方式以及它们的区别?

1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。

3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

struct 的成员默认是公有的,而类的成员默认是私有的。

在其他方面是功能相当的。从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用struct关键字,否则,你应该使用class关键字。

30.当一个类A中没有任何成员变量与成员函数,这时sizeof(A)的值是多少?

答案:空类大小等于1,是因为编译器为了区分不同的类,在类中加的一个char型。

31. 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)

答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。

32. 比较C++中的4种类型转换方式?

C++中的4种类型转换方式

在一类东西都可以转, 但是不是一类的就不能转. 

比如你想把一个指针转成浮点数, 

都是编译时决定的. 

它更进一步的, 实现一些看起来没关系的两种类型转换. 

编译器会对你咆哮, "不许动, 那玩意是我 const 住的, 把你的爪子 

人的好. 让编译器来捍卫我的代码的安全.

33.分别写出BOOL,int,float,指针类型的变量a与“零”的比较语句。

<1>const常量有数据类型,而宏常量没有数据类型,编译器可以对前者进行类型安全检查,而对后者只进行字符替换,并且在字符替换时会发生意料不到的错误

<2>有些集成化的调试工具可以对const常量进行调试,但是不能对红常量进行调试

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

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

(1)修改内容上的差别

p[0] = ‘X’; // 编译器不能发现该错误,运行时错误

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

计算数组和指针的内存容量

36.类成员函数的重载、覆盖和隐藏区别?

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(4)virtual 关键字可有可无。

b.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(4)基类函数必须有virtual 关键字。

c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

37.求出两个数中的较大者

38.如何打印出当前源文件的文件名以及源文件的当前行号?

__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。

39. main主函数执行完毕后,是否可能会再执行一段代码,给出说明?

40.如何判断一段程序是由C 编译程序还是由C++编译程序编译的?

41.文件中有一组整数,要求排序后输出到另一个文件中

42.链表题:一个链表的结点结构

(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)

(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)

(3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk)

43.写一个函数找出一个整数数组中,第二大的数 (microsoft)

44.写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。

46.多重继承的内存分配问题

47.如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)

试题1字符串str1需要11个字节才能存放下(包括末尾的’/0’),而string只有10个字节的空间,strcpy会导致数组越界;

对试题2,指出库函数strcpy工作方式

  (1)字符串以’/0’结尾;

  (2)对数组越界把握的敏感度;

  (3)库函数strcpy的工作方式

49.如果编写一个标准strcpy函数

总分值为10,下面给出几个不同得分的答案:

2分 以下是引用片段:

  4分 以下是引用片段:

  //将源字符串加const,表明其为输入参数,加2分

  7分 以下是引用片段:

  //对源地址和目的地址加非0断言,加3分

  10分 以下是引用片段:

//为了实现链式操作,将目的地址返回,加3分!

读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:

试题4:以下是引用片段:

试题6:以下是引用片段:

试题7:以下是引用片段:

  ... //省略的其它语句

试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,

  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。

试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句

  后未判断内存是否申请成功,而且未对malloc的内存进行释放

试题7存在与试题6同样的问题,在执行

  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:

试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。

  对内存操作的考查主要集中在:

  (1)指针的理解;

  (2)变量的生存期及作用范围;

  (3)良好的动态内存申请和释放习惯。

  再看看下面的一段程序有什么错误:

  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为

已知String类定义如下:

尝试写出类的成员函数实现

答:防止该头文件被重复引用。

答:前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。

53.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?

C++语言支持函数重载,C语言不支持函数重载。C++提供了C连接交换指定符号extern “C”

首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数

作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:

该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。

同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

假设在C++中,模块A的头文件如下:

在模块B中引用该函数:

加extern "C"声明后的编译和连接方式

加extern "C"声明后,模块A的头文件变为:

在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:

(1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

(2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

所以,可以用一句话概括extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):实现C++与C及其它语言的混合编程。

明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧:

(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。

C++引用C函数例子工程中包含的三个文件的源代码如下:

如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。

(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。

C引用C++函数例子工程中包含的三个文件的源代码如下:

虽然传入的是short类型,但是short类型的构造函数被生命被explicit,也就是只能显示类型转换,不能使用隐式类型转换。

第一个是指针加减,按照的是指向地址类型的加减,只跟类型位置有关,q和p指向的数据类型以实际数据类型来算差一个位置,因此是1。而第二个加减是实际指针值得加减,在内存中一个double类型占据8个字节,因此是8

55请你分别画出OSI的七层网络结构图和TCP/IP的五层结构图。

56请你详细地解释一下IP协议的定义,在哪个层上面?主要有什么作用?TCP与UDP呢 ?

57.请问交换机和路由器各自的实现原理是什么?分别在哪个层次上面实现的?

交换机:数据链路层。路由器:网络层。

58.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?

全局变量和局部变量的区别主要在于生存周期不同,全局变量在整个程序生成期间可见,局部变量在自己的作用域内可见。全局变量的内存分配是静态的,位于PE文件在数据区,在main()前由C、C++运行期函数初始化,如果没有初值,会被初始化为0。局部变量的内存分配是动态的,位于线程堆栈中。如果没有初始化的,初值视当前内存内的值而定。

操作系统和编译器从定义变量为变量分配内存时,从变量的定义和存储区域来分别局部变量和全局变量

59.Windows程序的入口是哪里?写出Windows消息机制的流程。

<1>操作系统接收应用程序的窗口消息,将消息投递到该应用程序的消息队列中

<2>应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息,取出消息后,应用程序可以对消息进行一些预处理

<4>系统利用WNDCLASS结构体的ipfoWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理

60.解释局部变量、全局变量和静态变量的含义。

局部变量:在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外时不能使用这些变量的,它们称为局部变量;

1.主函数main中定义的变量也只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效

2.不同函数中可以使用名字相同的变量,它们代表不同的对象,互不干扰

3.形式参数也使局部变量

4.在一个函数内部,可以在复合语句中定义变量,这些变量只在本符合语句中有效

全局变量:在函数外定义的变量是外部变量,外部变量是全局变量,全局变量可以为本文件中其它函数所共用,它的有效范围从定义变量的位置开始到本源文件结束;

1.设全局变量的作用:增加了函数间数据联系的渠道

2.建议不再必要的时候不要使用全局变量,因为

a.全局变量在程序的全部执行过程中都占用存储单元;

b.它使函数的通用性降低了

c.使用全局变量过多,会降低程序的清晰性

3.如果外部变量在文件开头定义,则在整个文件范围内都可以使用该外部变量,如果不再文件开头定义,按上面规定作用范围只限于定义点到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在该函数中用关键字extern作外部变量说明

4.如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用;

静态变量:在程序运行期间分配固定的存储空间的变量,叫做静态变量

61.论述含参数的宏与函数的优缺点

1.函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。

2.函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。

3.对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。

4.调用函数只可得到一个返回值,而用宏可以设法得到几个结果。

5.使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不使源程序变长。

6.宏替换不占运行时间。而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。

一般来说,用宏来代表简短的表达式比较合适

1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数;

//假设线性表的双向链表存储结构

C++里面是不是所有的动作都是main()引起的?如果不是,请举例

64.static有什么用途?(请至少说明两种)

<1>限制变量的作用域(文件级的)

<2>设置变量的存储域(全局数据区)

65.引用与指针有什么区别?

1)引用必须被初始化,指针不必

2)引用初始化以后不能被改变,指针可以改变所指的对象

3)不存在指向空值的引用,但是存在指向空值的指针

66.描述实时系统的基本特性

在特定时间内完成特定的任务,实时性与可靠性

67.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

68.什么是平衡二叉树?

左右子树都是平衡二叉树,且左右子树的深度差值的绝对值不大于1

69.堆栈溢出一般是由什么原因导致的?

2.层次太深的递归调用

70.什么函数不能声明为虚函数?

一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:

虚函数必须是基类的非函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:

virtual 函数返回值类型 虚函数名(形参表)  { 函数体 }

虚函数的作用是实现,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。

当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。

动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:

指向基类的指针变量名->虚函数名(实参表)

基类对象的引用名. 虚函数名(实参表)

虚函数是C++多态的一种表现:

例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。  使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。 如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。  如果一个类包含了纯虚函数,称此类为 。 

二、什么函数不能声明为虚函数:

一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的。 

设置虚函数须注意: 

1:只有类的成员函数才能说明为虚函数; 

2:静态成员函数不能是虚函数; 

3:内联函数不能为虚函数; 

4:构造函数不能是虚函数; 

5:析构函数可以是虚函数,而且通常声明为虚函数。

类里面“定义”的成员函数是内联的,但是仍然可以成为虚函数,那么是不是可以说“内联函数不能成为虚函数”这句话有问题呢,是不是应该改成“显式定义的内联函数不能成为虚函数”。比如下面这个示例程序:

你可以发现,虽然f1在基类中定义的,按理说应该是内联函数,但是它仍然可以成为虚函数。

类中定义的成员函数(函数体在类中)能成为虚函数,大部分编译器能够将虽然声明为inline但实际上不能inline的函数自动改为不inline的。至于编译器会不会将inline and virtual的函数照模照样的实现,与编译器及优化方式有关。

要想成为虚函数,必须能够被取到地址.内联函数不能被取到地址所以不能成为虚函数. 

你写inline virtual void f(),不能保证函数f()一定是内联的,只能保证f()是虚函数(从而保证此函数一定不是内联函数) 

71.冒泡排序算法的时间复杂度是什么?

73.Internet采用哪种网络协议?该协议的主要层次结构?

tcp/ip 应用层/传输层/网络层/数据链路层/物理层

74.Internet物理地址和IP地址转换采用什么协议?

75.IP地址的编码分为哪俩部分?

IP地址由两部分组成,网络号和主机号,不过要和子网掩码按位与之后才能区分哪些是网络位哪些是主机位

76.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。

switch的参数不能为实型

78.局部变量能否和全局变量重名?

79.如何引用一个已经定义过的全局变量?

可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错

80.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?

可以,在不同的C文件中以static形式来声明同名全局变量,前提是其中只有一个C文件中对此变量赋初值,此时连接不会出错

81.语句for( ;1 ;)有什么问题?它是什么意思?

答 、前一个循环一遍再判断,后一个判断以后再循环

83.请写出下列代码的输出内容

84.statac 全局变量、局部变量、函数与普通全局变量、局部变量、函数有什么区别?static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。

这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。

从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。

static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件

static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;

static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。

85.设有以下说明和定义:

答 、结果是:___52____。DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20

87.用两个栈实现一个队列的功能?要求给出算法和思路!

设2个栈为A,B, 一开始均为空.

(1)判断栈B是否为空;

(2)如果不为空,则将栈A中所有元素依次pop出并push到栈B;

(3)将栈B的栈顶元素pop出;

88.在c语言库函数中将一个字符转换成长整型的函数是atol()吗?

功 能: 把字符串转换成长整型数

89.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

90.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

我在这想看到几件事情:

1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)

2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。

3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。

4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

91.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

这个测试是为下面的目的而设的:

1). 标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。

2). 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。

3). 懂得在宏中小心地把参数用括号括起来

4). 我也用这个问题开始讨论宏的副作用

92.预处理器标识#error的目的是什么?

93.嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?

这个问题用几个解决方案。我首选的方案是:

一些程序员更喜欢如下方案:

这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是:“我被教着这样做,但从没有想到过为什么。”这会给我留下一个坏印象。

94.用变量a给出下面的定义

95.关键字static的作用是什么?

1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变

2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所有函数访问,但不能被模块外其他函数访问,它是一个本地的全局变量

3)在模块内,一个被声明为静态的函数只可能被这一模块内的其他函数调用,那就是,这个函数被限制在声明它的模块的本地范围内使用

96.关键字const是什么含意?

我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:

1). 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)

2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。

3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

97.关键字volatile有什么含意 并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

1). 并行设备的硬件寄存器(如:状态寄存器)

3). 多线程应用中被几个任务共享的变量

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。

假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。

1). 一个参数既可以是const还可以是volatile吗?解释为什么。

2). 一个指针可以是volatile 吗?解释为什么。

3). 下面的函数有什么错误:

1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

98.下面的代码输出是什么,为什么?

这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答案是输出是“>6”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。

99.C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?

这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成:

如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题

100.线形表a、b为两个有序升序的线形表,编写一程序,使两个有序线形表合并成一个有序升序线形表

101.用递归算法判断数组a[N]是否为一个递增数组。

递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:

102.编写算法,从10亿个浮点数当中,选出其中最大的10000个 

用外部排序,在《数据结构》书上有 

《计算方法导论》在找到第n大的数的算法上加工 (注意:先将数据进行分割成数据量小的一些文件,如1000000个数据为一个文件,然后将每个文件数据进行排序,用快速排序法排序,然后使用K路合并法将其合并到一个文件下,取出排序好的最大的10000个数据)

1.给两个数组和他们的大小,还有一动态开辟的内存,求交集,把交集放到动态内存dongtai,并且返回交集个数

2.单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!

109.什么是预编译,何时需要预编译?

预编译又称为预处理,是做些代码文本的替换工作,处理#开头的指令,预编译指令指示了程序正式编译前就有编译器进行的操作,可以放在程序中的任何位置

c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件编译

总是使用不经常改动的大型代码体

程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项,在这种情况下,可以将所有包含文件预编译为一个预编译头

107.ASDL使用的是什么协议?并进行简单描述?

105.判断字符串是否为回文

110.进程和线程的区别

什么是进程,普通的解释进程是程序的一次执行,而什么是线程,线程可以理解为进程中的执行的一段程序片段

进程是独立的,这表现在内存空间,上下文环境,线程运行在进程空间内,一般来讲,进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间,统一进程中的两段代码不能够同时执行,除非引入线程,线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除,线程占用资源要少于少于进程所占用的资源,进程和线程都可以有优先级,在线程系统中进程也是一个线程,可以将进程理解为一个程序的第一个线程

1)地址空间:进程至少有一个线程,线程共享进程的地址空间,而进程有自己独立的地址空间

2)进程是资源分配和拥有的单位,同一进程内的线程共享进程的资源

3)线程是处理器调度的基本单位,但进程不是

111.插入排序和选择排序

(假定从大到小排序)依次从后面拿一个数和前面已经排好序的数进行比较,比较的过程是从已经排好序的数中最后一个数开始比较,如果比这个数,继续往前面比较,直到找到比它大的数,然后就放在它的后面,如果一直没有找到,肯定这个数已经比较到了第一个数,那就放到第一个数的前面。

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。

112.运算符优先级问题

能正确表示a和b同时为正或同时为负的逻辑表达式是(D )。

以下关于运算符优先顺序的描述中正确的是(C)。 

A、关系运算符<算术运算符<赋值运算符<逻辑与运算符 

B、逻辑与运算符<关系运算符<算术运算符<赋值运算符 

C、赋值运算符<逻辑与运算符<关系运算符<算术运算符 

D、算术运算符<关系运算符<赋值运算符<逻辑与运算符

/* 将输入的字符串反转。

方法二:使用 C风格字符串 char *

/* 将输入的字符串反转。

/* 将输入的字符串反转。

* 方法三:使用 string 的另一个方法。

114.交换两个数的宏定义

我说过游标是指针,但不仅仅是指针。游标和指针很像,功能很像指针,但是实际上,游标是通过重载一元的”*”和”->”来从容器中间接地返回一个值。将这些值存储在容器中并不是一个好主意,因为每当一个新值添加到容器中或者有一个值从容器中删除,这些值就会失效。在某种程度上,游标可以看作是句柄(handle)。通常情况下游标(iterator)的类型可以有所变化,这样容器也会有几种不同方式的转变:

iterator——对于除了vector以外的其他任何容器,你可以通过这种游标在一次操作中在容器中朝向前的方向走一步。这意味着对于这种游标你只能使用“++”操作符。而不能使用“--”或“+=”操作符。而对于vector这一种容器,你可以使用“+=”、“—”、“++”、“-=”中的任何一种操作符和“<”、“<=”、“>”、“>=”、“==”、“!=”等比较运算符。

从语法上,在C++中(只讨论C++中)。class和struct做类型定义时只有两点区别:

(一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;

(二)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。

最后,作为语言的两个关键字,除去定义类型时有上述区别之外,另外还有一点点:“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。

关于使用大括号初始化 

class和struct如果定义了构造函数的话,都不能用大括号进行初始化

如果没有定义构造函数,struct可以用大括号初始化。

如果没有定义构造函数,且所有成员变量全是public的话,可以用大括号初始化。

119.关系模型的基本概念

关系数据库以关系模型为基础,它有以下三部分组成:

●数据结构——模型所操作的对象、类型的集合

●完整性规则——保证数据有效、正确的约束条件

●数据操作——对模型对象所允许执行的操作方式

关系(Relation)是一个由行和列组成的二维表格,表中的每一行是一条记录(Record),每一列是记录的一个字段(Field)。表中的每一条记录必须是互斥的,字段的值必须具有原子性。

SQL(结构化查询语言)是关系数据库语言的一种国际标准,它是一种非过程化的语言。通过编写SQL,我们可以实现对关系数据库的全部操作。

●数据定义语言(DDL)——建立和管理数据库对象

●数据操纵语言(DML)——用来查询与更新数据

●数据控制语言(DCL)——控制数据的安全性

事务处理系统的典型特点是具备ACID特征。ACID指的是Atomic(原子的)、Consistent(一致的)、Isolated(隔离的)以及Durable(持续的),它们代表着事务处理应该具备的四个特征:

原子性:组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分

一致性:在事务处理执行之前和之后,数据是一致的。

隔离性:一个事务处理对另一个事务处理没有影响。

持续性:当事务处理成功执行到结束的时候,其效果在数据库中被永久纪录下来。

121.C语言中结构化程序设计的三种基本控制结构

顺序结构、选择结构、循环结构

123.三种基本的数据模型

按照数据结构类型的不同,将数据模型划分为层次模型、网状模型、关系模型

我要回帖

更多关于 数学小括号中括号大括号 的文章

 

随机推荐