9个面试必备问题 *

最好的C开发人员和工程师可以回答的全面来源的基本问题. 在我们社区的推动下,我们鼓励专家提交问题并提供反馈.

现在就雇佣一名顶级C开发人员
Toptal标志是顶级自由软件开发人员的专属网络吗, 设计师, 金融专家, 产品经理, 和世界上的项目经理. 顶级公司雇佣Toptal自由职业者来完成他们最重要的项目.

面试问题

1.

什么是void指针? 你能在不知道void指针类型的情况下解引用它吗?

查看答案

void指针是一种可用于指向任意类型的任何数据的指针. void指针只有在显式强制转换之后才能解引用. 例如:

Int a = 5;
Void *b = &a;
printf (" % d \ n”* ((int *) b));
2.

两者的区别是什么 #包括“..." and #include <...>?

查看答案

不同之处在于预处理器在哪里查找要包含的文件. For the include 指令,文件名带双引号, 预处理器将其对文件的搜索限制在当前源文件所在的同一目录中, 然后转到编译器预先指定的标准目录. 另一方面, 当指令使用尖括号时, 预处理器在编译器预先指定的目录中搜索文件——通常是标准库头文件所在的目录.

3.

什么是悬空指针? 悬空指针与内存泄漏有何不同?

查看答案

悬空指针指向已经释放的内存位置. 例如:

Int *a = malloc(sizeof(Int));
free(a);
// a现在是一个悬空指针

内存泄漏与悬空指针完全相反. 当内存位置没有被释放时,就会发生内存泄漏,但是没有办法引用它们(例如.e.,没有指针指向它们).

Int *a = malloc(sizeof(Int));
a = 0;
//现在a不再指向我们刚刚分配的内存,导致内存泄漏

与带有垃圾收集器的高级语言不同, 在用C语言编程时,始终跟踪已分配的内存是至关重要的.

申请加入Toptal的发展网络

并享受可靠、稳定、远程 自由C语言开发者职位

申请成为自由职业者
4.

下面的语句声明了什么?

Char (*x) (Char *);
查看答案

上面的语句声明 x 作为指向函数的指针,该函数接受单个字符指针参数,并返回一个字符.

5.

当执行以下代码时,输出将是什么? Explain.

#include 
#define SQUARE(a) (a)*(a)

Int main() {
    printf (" % d \ n”,平方(4));
    Int x = 3;
    printf (" % d \ n”,广场(+ + x));
}
查看答案

答案是事实 未定义的,并取决于所使用的编译器. 一些编译器会导致 16 and 20,而其他人则会生产 16 and 25.

人们可能会期待第二次使用 SQUARE 宏观收益 16,就像第一次使用的 SQUARE macro. However, 宏由预处理器处理, 在实际编译开始之前进行的步骤. 展开第二个宏将显示实际编译的内容:

(++x)*(++x)

预增量操作的求值 ++x C语言中的未定义行为是从哪里来的. 对于某些编译器,宏将减少为 (4)*(5),而在其他情况下,它将被计算为 (5)*(5).

这篇文章 进一步讨论这种行为.

6.

为什么使用它通常是一个坏主意 gets()? 建议一个变通办法.

查看答案

这个函数 gets()stdin 并将它们存储在提供的输入缓冲区中. However, gets() 会继续阅读直到遇到换行符. 除非缓冲区足够大,或者被读取的行长度事先已知, gets() 可能溢出输入缓冲区,并开始覆盖内存,它不应该, 造成严重破坏或打开安全漏洞.

解决这个问题的一种方法是使用 fgets(). 它允许你对读取的最大字符数进行限制:

Fgets (b, 124, stdin);
7.

结构体和联合的区别是什么?

查看答案

结构体是一种复杂的数据类型,它允许将多个变量存储在指定内存块的组中. 结构体的每个成员变量可以存储不同的数据,并且它们都可以同时使用.

Struct a {
    int x;
    char y;
} a;

例如,您可以将一个整数存储在 x,和和一个字符 y 以上,相互独立.

A union, 另一方面, 将任何成员变量的内容存储在完全相同的内存位置. 这允许在相同的内存位置存储不同类型的数据. 结果是,给一个成员赋值将改变所有其他成员的值. 与struct不同,在任何给定时间,联合类型中可能只有一个成员是有用的.

union b {
    int x;
    char y;
} b;

例如,将字符存储在 y 可能会自动更改读取的整数 x 对无意义或不可预测的事物.

8.

下面的代码片段使用强制类型转换将浮点数转换为整数:

浮动f = 1.0;

Int i1 = (Int) f;
Int i2 = * (Int *) &f;

printf (" % d \ n, i1);
printf (" % d \ n, i2);

输出结果如下:

1
1065353216

你能解释一下为什么结果不同吗?

查看答案

第一个强制转换操作正确地将浮点数转换为整数, 由C标准指定. 第二次转换, however, 是否首先将浮点指针转换为整数指针,然后解引用以获得最终结果. 这样,编译器就可以有效地处理浮点数(通常以IEEE浮点格式存储)中的原始位,就好像它们是整数的位一样. 除了得到错误的结果之外,您还可能执行“错误读取”操作,在以下情况下 sizeof (int) 大于 sizeof(浮动) (e.g. 在某些64位架构上).

尽管这种特殊的代码不太可能, 它演示了当只有指向要转换的变量的指针可用时,类型转换所涉及的风险之一. 实际上,指针必须解引用 before 它是铸造的.

9.

如果在32位操作系统上运行下面的程序,输出结果是什么?

#include 
int main ()
{
  int a=-2;
  printf("%x",a>>3);
}
查看答案

在32位操作系统中,整数被存储为4字节.

Since a 是负的,它会存储在2的补码中吗. 当一个整数为负时我们想右移n位, 我们需要在前面加上1(而不是0)!)到左手边. 因此,答案是 0xFFFF (%x 输出十六进制的值).

面试不仅仅是棘手的技术问题, 所以这些只是作为一个指南. 并不是每一个值得雇佣的“A”候选人都能回答所有的问题, 回答所有问题也不能保证成为A级考生. 一天结束的时候, 招聘仍然是一门艺术,一门科学,需要大量的工作.

为什么Toptal

厌倦了面试候选人? 不知道该问什么才能让你得到一份好工作?

让Toptal为你找到最合适的人.

现在就雇佣一名顶级C开发人员

我们的独家C开发人员网络

希望找到一份C语言开发人员的工作?

让Toptal为你找到合适的工作.

申请成为C开发人员

工作机会从我们的网络

提出面试问题

提交的问题和答案将被审查和编辑, 并可能会或可能不会选择张贴, 由Toptal全权决定, LLC.

*所有字段均为必填项

寻找C开发人员?

寻找 C开发人员? 查看Toptal的C开发人员.

詹姆斯·科尔

自由C开发员
CanadaToptal成员 Since 2020年6月18日

James已经做了25年的独立顾问,使用了广泛的技术和语言. 他对软件充满热情, 在领导团队的同时,不断提升自己的技能,掌握新技术, 进行联合应用开发, 做演讲.

显示更多

菲比召唤

自由C开发员
美国Toptal成员 Since 2020年4月15日

Phoebe是一名全栈开发人员,在各种行业和公司规模的软件构建方面拥有超过9年的经验. 她的主要关注点是服务器端开发, 但她也喜欢使用现代UI解决方案. 菲比对她的代码一丝不苟, 热心倡导最佳实践, 并且知道沟通在交付卓越产品中是多么重要.

显示更多

尼古拉Vasović

自由C开发员
SerbiaToptal成员 Since 2019年10月4日

作为一名软件工程硕士研究生和国家著名奖学金获得者, Nikola在Toptal开始了他的全栈开发生涯. 利用Flutter的专业知识进行跨平台移动开发, 他专门为初创公司精简MVP产品发布流程. Nikola是Varius Development的联合创始人,并担任首席技术官,在与全球知名企业合作的同时,扩展了他的DevOps和PM专业知识, 转变为多才多艺的IT专业人士.

显示更多

Toptal连接 Top 3% 世界各地的自由职业人才.

加入Toptal社区.

了解更多