C 语言编程面试问题与答案

2025年4月10日 | 18 分钟阅读
C Interview Questions

下面列出了 50 个最常被问到的 C 语言编程面试问题与答案。

1) C 语言是什么?

C 是一种中级、过程式编程语言。过程式编程语言也被称为结构化编程语言,它是一种将大型程序分解为更小模块的技术,每个模块都使用结构化代码。这种技术可以最大限度地减少错误和误解。 更多详情。


2) 为什么 C 被称为母语言?

C 被称为母语言,因为大多数编译器和 JVM 都是用 C 语言编写的。在 C 语言之后开发的多数语言,如 C++、Python、Rust、JavaScript 等,都大量借鉴了 C 语言。它引入了数组、函数、文件处理等新的核心概念,这些概念在这些语言中都被使用。 更多详情。


3) 为什么 C 被称为中级编程语言?

C 被称为中级编程语言,因为它结合了低级和高级编程语言的特性。我们可以使用 C 语言作为系统编程语言来开发操作系统,也可以作为应用程序编程语言来生成菜单驱动的客户计费系统。 更多详情。


4) 谁是 C 语言的创始人?

丹尼斯·里奇 (Dennis Ritchie)。 更多详情。


5) C 语言是什么时候开发的?

C 语言于 1972 年在 AT&T 的贝尔实验室开发。 更多详情。


6) C 语言有哪些特点?

C 语言的主要特点如下:

  • 简单: C 语言是一种简单的语言,因为它遵循结构化方法,即将一个程序分解成多个部分。
  • 可移植: C 语言具有高度的可移植性,这意味着程序一旦编写完成,就可以在任何机器上运行,几乎不需要修改。
  • 中级: C 是一种中级编程语言,因为它结合了低级语言和高级语言的特性。
  • 结构化: C 是一种结构化语言,因为 C 程序被分解成多个部分。
  • 速度快: C 语言速度非常快,因为它使用了一套强大的数据类型和运算符。
  • 内存管理: C 提供了内置的内存函数,可以节省内存并提高我们程序的效率。
  • 可扩展: C 是一种可扩展的语言,因为它可以在未来采纳新的特性。
更多详情。

7) printf() 和 scanf() 函数的用途是什么?

printf(): printf() 函数用于在屏幕上打印整数、字符、浮点数和字符串值。

以下是格式说明符:

  • %d: 它是用于打印整数值的格式说明符。
  • %s: 它是用于打印字符串的格式说明符。
  • %c: 它是用于显示字符值的格式说明符。
  • %f: 它是用于显示浮点值的格式说明符。

scanf(): scanf() 函数用于从用户那里获取输入。

更多详情。

8) C 语言中局部变量和全局变量有什么区别?

以下是局部变量和全局变量之间的区别:

比较基础局部变量全局变量
声明在函数或块内部声明的变量被称为局部变量。在函数或块外部声明的变量被称为全局变量。
范围变量的作用域仅限于声明它们的函数内部。变量的作用域在整个程序中都可用。
访问变量只能被声明它们的函数内部的语句访问。整个程序中的任何语句都可以访问变量。
寿命变量的生命周期在进入函数块时创建,在其退出时销毁。变量的生命周期在程序执行期间一直存在。
存储除非另有说明,变量存储在栈中。编译器决定变量的存储位置。
更多详情。

9) C 语言中静态变量的用途是什么?

以下是静态变量的用途:

  • 声明为 static 的变量被称为静态变量。静态变量在多次函数调用之间保持其值。
  • 使用静态变量是因为静态变量的作用域在整个程序中都可用。所以,我们可以在程序的任何地方访问静态变量。
  • 静态变量初始时被初始化为零。如果我们更新了变量的值,那么更新后的值将被赋给它。
  • 静态变量被用作所有方法共享的公共值。
  • 静态变量在内存堆中只初始化一次,以减少内存使用。
更多详情。

10) C 语言中函数的用途是什么?

C 函数的用途是:

  • C 函数用于避免在我们的程序中一遍又一遍地重写相同的代码。
  • C 函数可以从我们程序的任何地方被调用任意次数。
  • 当一个程序被划分为多个函数时,我们程序的任何部分都可以被轻易地追踪。
  • C 函数提供了可重用性的概念,即将大任务分解为小任务,从而使 C 程序更易于理解。
更多详情。

11) C 语言中按值调用和按引用调用有什么区别?

以下是按值调用和按引用调用之间的区别:

 按值调用按引用调用
描述当值的副本传递给函数时,原始值不会被修改。当值的副本传递给函数时,原始值会被修改。
内存位置实际参数和形式参数在不同的内存位置创建。实际参数和形式参数在相同的内存位置创建。
安全性在这种情况下,实际参数保持安全,因为它们不能被修改。在这种情况下,实际参数不可靠,因为它们会被修改。
参数实际参数的副本被传递给形式参数。实际参数的地址被传递给它们各自的形式参数。

按值调用的例子

输出

Value of a is: 10
Value of b is: 20

按引用调用的例子

输出

Value of a is: 13
Value of b is: 17

更多详情。


12) C 语言中的递归是什么?

当一个函数调用自身时,这个过程被称为递归。调用自身的函数被称为递归函数。

递归函数分为两个阶段:

  1. 递推阶段
  2. 回归阶段

递推阶段:当递归函数调用自身时,这个阶段在达到条件时结束。

回归阶段:当达到条件时,回归阶段开始,控制权返回到原始调用处。

递归的例子

输出

factorial of a number is 120

更多详情。


13) C 语言中的数组是什么?

数组是一组相似类型元素的集合。它具有连续的内存位置。它使代码优化、易于遍历和排序。数组的大小和类型在声明后不能更改。

数组有两种类型:

  • 一维数组:一维数组是按顺序存储元素的数组。

语法

  • 多维数组:多维数组是包含一个以上数组的数组。

语法

数组的例子

输出

1 2 3 4 5
更多详情。

14) C 语言中的指针是什么?

指针是一个引用某个值的地址的变量。它使代码优化,性能更快。每当在程序中声明一个变量时,系统会为该变量分配一些内存。该内存包含一个地址编号。持有这个地址编号的变量被称为指针变量。

例如

上面的语法表示 p 是一个指针变量,它持有给定数据类型值的地址编号。

指针的例子

输出

Address value of 'a' variable is 428781252

更多详情。


15) C 语言中指针的用途是什么?

  • 访问数组元素:指针用于遍历整数和字符串数组。字符串是一个以空字符 '\0' 结尾的字符数组。
  • 动态内存分配:指针用于在程序执行期间分配和释放内存。
  • 按引用调用:指针用于将变量的引用传递给其他函数。
  • 数据结构,如树、图、链表等:指针用于构建不同的数据结构,如树、图、链表等。

16) C 语言中的 NULL 指针是什么?

一个不引用任何值的地址,而是引用 NULL 的指针被称为 NULL 指针。当我们给任何类型的指针赋一个 '0' 值时,它就变成了一个 NULL 指针。

更多详情。


17) C 语言中的远指针是什么?

一个可以访问 RAM 所有 16 个段(整个驻留内存)的指针被称为远指针。远指针是一个 32 位指针,用于获取给定段之外内存中的信息。


18) C 语言中的悬挂指针是什么?

  • 如果一个指针指向某个内存位置,但同时另一个指针删除了第一个指针所占用的内存,而第一个指针仍然指向那个内存位置,那么第一个指针就被称为悬挂指针。这个问题被称为悬挂指针问题。
  • 当对象被删除而没有修改指针的值时,就会出现悬挂指针。指针指向了已释放的内存。

让我们通过一个例子来看一下。

在上面的例子中,最初内存被分配给指针变量 ptr,然后内存从指针变量中被释放。现在,指针变量,即 ptr,变成了一个悬挂指针。

如何克服悬挂指针的问题

悬挂指针的问题可以通过给悬挂指针赋一个 NULL 值来克服。让我们通过一个例子来理解这一点:

在上面的例子中,从指针变量释放内存后,ptr 被赋为 NULL 值。这意味着 ptr 不指向任何内存位置。因此,它不再是一个悬挂指针。


19) C 语言中的指针的指针是什么?

在指针的指针概念中,一个指针引用另一个指针的地址。指针的指针是一个指针链。通常,指针包含一个变量的地址。而指针的指针则包含第一个指针的地址。让我们通过一个例子来理解这个概念:

在上面的例子中,pptr 是一个双重指针,指向 ptr 变量的地址,而 ptr 指向 'a' 变量的地址。

更多详情。


20) 什么是静态内存分配?

  • 在静态内存分配的情况下,内存是在编译时分配的,并且在程序执行时无法增加内存。它用于数组。
  • 静态内存中变量的生命周期是程序的生命周期。
  • 静态内存是使用 static 关键字分配的。
  • 静态内存是使用栈或堆实现的。
  • 需要指针来访问静态内存中的变量。
  • 静态内存比动态内存快。
  • 在静态内存中,需要更多的内存空间来存储变量。

上面的例子创建了一个整数类型的数组,数组的大小是固定的,即 10。

更多详情。


21) 什么是动态内存分配?

  • 在动态内存分配的情况下,内存是在运行时分配的,并且在执行程序时可以增加内存。它用于链表。
  • 需要在运行时使用 malloc() 或 calloc() 函数来分配内存。
  • 内存的分配或释放是在程序执行时完成的。
  • 不需要动态指针来访问内存。
  • 动态内存是使用数据段实现的。
  • 存储变量需要较少的内存空间。

上面的例子在运行时分配内存。

更多详情。


22) C 语言中用于动态内存分配的函数有哪些?

语法

语法

语法

在上面的语法中,ptr 被分配了一个新的大小。

语法

上面的语法从指针变量 ptr 中释放了内存。

  1. malloc()
    • malloc() 函数用于在程序执行期间分配内存。
    • 它不会初始化内存,但会带有垃圾值。
    • 如果无法分配请求的空间,它将返回一个空指针。
  2. calloc()
    • calloc() 与 malloc() 函数相同,唯一的区别是它将内存初始化为零值。
  3. realloc()
    • realloc() 函数用于将内存重新分配到新的大小。
    • 如果内存中没有足够的空间,则会分配一个新的块来容纳现有数据。
  4. free(): free() 函数释放由 calloc() 或 malloc() 函数分配的内存。

更多详情。


23) malloc() 和 calloc() 有什么区别?

 calloc()malloc()
描述malloc() 函数分配一个请求内存的单块。calloc() 函数分配多个请求内存的块。
初始化它将内存内容初始化为零。它不初始化内存内容,所以它带有垃圾值。
参数数量它包含两个参数。它只包含一个参数。
返回值它返回一个指向已分配内存的指针。它返回一个指向已分配内存的指针。

更多详情。


24) 什么是结构体?

  • 结构体是一种用户定义的数据类型,允许在单个单元中存储多种类型的数据。它占用的内存是其所有成员内存的总和。
  • 结构体成员只能通过结构体变量来访问。
  • 结构体变量访问的是同一个结构体,但为每个变量分配的内存是不同的。

结构体的语法

让我们看一个简单的例子。

输出

Enter the name shikha
Enter the age 26
Name and age of a student: shikha,26  

更多详情。


25) 什么是联合体?

  • 联合体是一种用户定义的数据类型,允许在单个单元中存储多种类型的数据。然而,它并不占用所有成员内存的总和。它只占用最大成员的内存。
  • 在联合体中,我们一次只能访问一个变量,因为它为联合体的所有成员分配了一个公共的存储空间。

联合体的语法

让我们看一个简单的例子

输出

value of a is 1085485921
value of b is 5.600022
value of ch is a

在上面的例子中,a 和 b 的值会损坏,只有变量 ch 显示实际的输出。这是因为联合体的所有成员共享同一个内存空间。因此,只有当前被更新的变量 ch 的值是有效的。

更多详情。


26) C 语言中的 auto 关键字是什么?

在 C 语言中,函数的每个局部变量都被称为自动(auto)变量。在函数块内部声明的变量被称为局部变量。局部变量也被称为自动变量。在变量的数据类型前使用 auto 关键字是可选的。如果局部变量没有存储任何值,那么它包含的是一个垃圾值。


27) sprintf() 函数的用途是什么?

sprintf() 代表“string print”(字符串打印)。sprintf() 函数不会在控制台屏幕上打印输出。它将数据传输到缓冲区。它返回字符串中存在的总字符数。

语法

让我们看一个简单的例子

输出

value of n is 9

28) 我们可以在没有 main() 函数的情况下编译程序吗?

是的,我们可以编译,但无法执行。

但是,如果我们使用 #define,我们可以在不使用 main() 函数的情况下编译并运行一个 C 程序。例如:

更多详情。


29) 什么是标记(token)?

标记(Token)是一个标识符。它可以是常量、关键字、字符串字面量等。标记是程序中最小的独立单元。C 语言有以下几种标记:

  1. 标识符:标识符指的是变量的名称。
  2. 关键字:关键字是编译器已解释的预定义词。
  3. 常量:常量是在程序执行期间不能更改的固定值。
  4. 运算符:运算符是执行特定操作的符号。
  5. 特殊字符:除字母和数字外的所有字符都被视为特殊字符。

30) 什么是命令行参数?

在执行程序时传递给 main() 函数的参数被称为命令行参数。例如:


31) ANSI 是什么的缩写?

ANSI 代表“美国国家标准协会”(American National Standard Institute)。它是一个维护包括摄影胶片、计算机语言、数据编码、机械零件、安全等广泛学科标准的组织。


32) getch() 和 getche() 有什么区别?

getch() 函数从键盘读取单个字符。它不使用任何缓冲区,所以输入的数据不会显示在输出屏幕上。

getche() 函数从键盘读取单个字符,但数据会显示在输出屏幕上。按 Alt+F5 可以看到输入的字符。

让我们看一个简单的例子

输出

Enter a character
value of ch is a
Enter a character again a
value of ch is a

在上面的例子中,通过 getch() 函数输入的值没有显示在屏幕上,而通过 getche() 函数输入的值则显示在屏幕上。


33) 什么是换行转义序列?

换行转义序列由“\n”表示。它在输出屏幕上插入一个新行。

更多详情。

34) 在丹尼斯·里奇之后,谁是设计 C 语言的主要贡献者?

布莱恩·柯林汉 (Brian Kernighan)。


35) near、far 和 huge 指针有什么区别?

一个虚拟地址由选择器偏移量组成。

near 指针没有显式的选择器,而 far 和 huge 指针有显式的选择器。当您对 far 指针执行指针运算时,选择器不会被修改,但在 huge 指针的情况下,它可以被修改。

这些是非标准关键字,并且是特定于实现的。在现代平台中,它们已不再适用。


36) 标识符的最大长度是多少?

理论上是 32 个字符,但具体取决于实现。


37) 什么是类型转换?

类型转换是将一种数据类型转换为另一种数据类型的过程。如果我们想将浮点类型的值存储到 int 类型中,我们将显式地将数据类型转换为另一种数据类型。

语法


38) C 语言中打开和关闭文件的函数是什么?

fopen() 函数用于打开文件,而 fclose() 用于关闭文件。


39) 在 C 语言中,我们可以使用指针访问数组吗?

是的,通过将数组的基地址存入指针,我们可以使用指针访问数组。


40) 什么是无限循环?

一个连续运行不确定次数的循环被称为无限循环。

无限 For 循环

无限 While 循环

无限 Do-While 循环


41) 编写一个不使用分号打印 "hello world" 的程序?

更多详情。

42) 编写一个不使用第三个变量交换两个数字的程序?

更多详情。

43) 编写一个不使用递归打印斐波那契数列的程序?

更多详情。

44) 编写一个使用递归打印斐波那契数列的程序?

更多详情。

45) 编写一个 C 语言程序来检查素数?

更多详情。

46) 编写一个 C 语言程序来检查回文数?

更多详情。

47) 编写一个不使用递归打印给定数字阶乘的程序?

更多详情。

48) 编写一个使用递归打印给定数字阶乘的程序?

更多详情。

49) 编写一个 C 语言程序来检查阿姆斯特朗数?

更多详情。

50) 编写一个 C 语言程序来反转给定的数字?

更多详情。