面试中你不可回避的C、C++的问题(一)

1.      局部变量与全局变量问题 (使用’ ::’)

2.      如何在另个文件中引用一个全局变量 (extern)

3.      全局变量可以定义被多个C文件包含,并且是static

4.      static全局变量就是静态全局变量,static限制了全局变量的作用域

5.      static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝.

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

7.      两个栈实现一个队列

8.      atol、atoi、fprintf---将字符串转换成数字

9.      两个数交换

#include <stdio.h>
#include <math.h>

int main()
{
	int a = 100,b=1000;
	int max = ((a+b)+abs(a-b))/2;
	printf("max = %d\n",max);
	max = a-b;
	char *strs[2] = {"a bigger","b bigger"};
	max = unsigned(max) >> (sizeof(int)*8-1);
	printf("max = %s\n",strs[max]);
	return 0;
}

10.  Extern “C”---extern也可用来进行链接指定.C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,

       而C语言则不会,因此会         造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,

       不要给我生成用于链接的中间函数名。

11.  C++语言的创建初衷是“abetter C”,但是这并不意味着C++中类似C语言的全局变量函数所采用的编译和连接方式与C语言完全相同

12.  假设某个函数的原型为:voidfoo( int x, int y );

13.  该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,

        但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,

        C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, inty )与void foo( int x, float y )编译生成的符号是不相同的,

        后者为_foo_int_float。同样地,C++中的变量除支持局部变量外,还支持类成员变量全局变量。用户所编写程序的类成员变量可能与全局变量同名,

        我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

14.  Volatile

        a)volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,

           基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。

        b)volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.简单地说就是防止编译器对代码进行优化.

        c)一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

          精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

       d)使用的地方:中断服务程序中修改的供其他程序检测的变量,多任务环境下的共享标志,存储器映射的硬件寄存器通常也要加

15.atexit()函数的使用

/*
很多时候我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种
比如main()函数运行结束、在程序的某个地方用exit()结束程序、用户通过Ctrl+C或Ctrl+break操作来终止程序等等
因此需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理
方法就是用atexit()函数来注册程序正常终止时要被调用的函数
atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数。
atexit()的函数原型是:int atexit (void (*)(void));
在一个程序中最多可以用atexit()注册32个处理函数,这些处理函数的调用顺序与其注册的顺序相反
也即最先注册的最后调用,最后注册的最先调用。
*/
#include <stdlib.h>
#include <stdio.h>

int atexit(void (*function)(void));

void fn1(void),fn2(void),fn3(void),fn4(void);

int main(void)
{
	atexit(fn1);
	atexit(fn2);
	atexit(fn3);
	atexit(fn4);
	printf("This is executed first!\n");
	return 0;
}

void fn1()
{
	printf(" next!\n");
}
void fn2()
{
	printf(" executed");
}
void fn3()
{
	printf(" is");
}
void fn4()
{
	printf("This");
}


  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值