c语言基础例题(面试必学)

一、局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用” :: ”
局部变量可以与全局变量同名, 在函数内引用这个变量时, 会用到同名的局部变
量,而不会用到全局变量。 对于有些编译器而言, 在同一个函数内可以定义多个
同名的局部变量, 比如在两个循环体内都定义一个同名的局部变量, 而那个局部
变量的作用域就在那个循环体内

二、程序的内存分配
答:一个由 c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack )—由编译器自动分配释放,存放函数的参数值,局部变量的值
等。其操作方式类似于数据结构中的栈。
2、堆区( heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能
由 OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表
3、全局区(静态区)( static )—全局变量和静态变量的存储是放在一块的,
初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静
态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码

int a=0; // 全局初始化区
char *p1; // 全局未初始化区
main()
{
int b;char s[]= ”abc”; // 栈
char *p2; // 栈
char *p3=123456; //123456 \0 在常量区, p3 在栈上。
static int c=0// 全局(静态)初始化区
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); // 分配得来得 10 和 20 字节的区域就在堆区。
strcpy(p1,123456); //123456 \0 放在常量区,编译器可能会将它与 p3 所
向”123456″优化成一个地方。
}

三、请说出 const 与#define 相比,有何优点?
答:Const 作用:定义常量、修饰函数参数、 修饰函数返回值三个作用。 被 Const
修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
1) const 常量有数据类型, 而宏常量没有数据类型。 编译器可以对前者进行类
型安全检查。 而对后者只进行字符替换, 没有类型安全检查, 并且在字符替换可
能会产生意料不到的错误。
2) 有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进
行调试。

四、以下 3 个有什么区别
char * const p; // 常量指针, 指针指向不可以改,指针指向的值可以更改eg *p=20(修饰常量)
char const * p ;// 指向常量的指针,指向的常量值不可以改(修饰指针)
const char *p ; // 同上

五、写出程序运行结果

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));
}
}

// static 会保存上次结果
输出: 8,10,12,14,16

六、“引用”与指针的区别是什么?
答 、1) 引用必须被初始化,指针不必。
2) 引用初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引用,但是存在指向空值的指针。
指针通过某个指针变量指向一个对象后, 对它所指向的变量间接操作。 程序中使
用指针,程序的可读性差; 而引用本身就是目标变量的别名, 对引用的操作就是
对目标变量的操作。
流操作符 <<和>>、赋值操作符 =的返回值、拷贝构造函数的参数、赋值操作符 =
的参数、其它情况都推荐使用引用。

七、嵌入式系统中经常要用到无限循环
1)

while(1)
{
}

用圆括号括起的判断部分,要求的不是代码块,而是一个,仅一个表达式。这就要求每次判断,都要执行这个表达式,以求得表达式的值,来决定是否继续执行循环。换句话,每次循环之前,都必须执行一次这个表达式

2

for(;;)
{
}

判断区里要求的是 代码块,如果要无条件循环,只需置其为空,与 while 循环相比,节省了一次执行表达式的操作。中间没有条件就是无限循环

3)

Loop:
...
goto Loop;

八、中断( Interrupts )
答: 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种
扩展—让标准 C支持中断。具代表事实是,产生了一个新的关键字 __interrupt 。
下面的代码就使用了 __interrupt 关键字去定义了一个中断服务子程序 (ISR) ,
请评论一下这段代码的。

__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}

1)ISR 不能返回一个值。
2) ISR 不能传递参数。
3) 在许多的处理器 / 编译器中,浮点一般都是不可重入的。有些处理器 / 编译器
需要让额处的寄存器入栈, 有些处理器 / 编译器就是不允许在 ISR 中做浮点运算。
此外, ISR 应该是短而有效率的,在 ISR 中做浮点运算是不明智的。
4) 与第三点一脉相承, printf() 经常有重入和性能上的问题

九、下面的代码输出是什么,为什么?

void foo(void) 
{
 unsigned int a = 6; 
 int b = -20; (a+b > 6) ? puts(>6) : puts(<= 6"); 
 }

整数自动转换原则, 答案是输出是 ">6″。原因是当
表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类
型。因此 -20 变成了一个非常大的正整数,所以该表达式计算出的结果大于 6。

十、什么是预编译 , 何时需要预编译 ?
答:预编译又称为预处理 , 是做些代码文本的替换工作。处理 #开头的指令 , 比如
拷贝#include 包含的文件代码, #define 宏定义的替换 , 条件编译等,就是为编
译做的预备工作的阶段,主要处理 #开始的预编译指令,预编译指令指示了在程
序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
c 编译系统在对程序进行通常的编译之前,先进行预处理。 c 提供的预处理功能
主要有以下三种: 1)宏定义 2)文件包含 3)条件编译
1)总是使用不经常改动的大型代码体。
2)程序由多个模块组成, 所有模块都使用一组标准的包含文件和相同的编译选
项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

原文链接:http://blog.qmgua.com/?id=140

=========================================

http://blog.qmgua.com/ 为 “布尔博客” 唯一官方服务平台,请勿相信其他任何渠道。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸运的涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值