下面列出了几个最常见的 C 编程面试问题和答案。
1.什么是C语言?
C 是一种中级和过程式编程语言。过程编程语言也称为结构化编程语言,是一种将大型程序分解为更小的模块,每个模块都使用结构化代码的技术。这种技术最大限度地减少了错误和误解。
2.为什么C被称为母语?
C 被称为母语言,因为大多数编译器和 JVM 都是用 C 语言编写的。在 C 语言之后开发的大多数语言都大量借鉴了 C++、Python、Rust、javascript 等。它引入了这些语言中使用的新核心概念,如数组、函数、文件处理。
3.为什么C被称为中级编程语言?
C 被称为中级编程语言,因为它结合了低级和高级编程语言。我们可以使用 C 语言作为系统编程来开发操作系统,也可以使用应用程序编程来生成菜单驱动的客户驱动计费系统。
4.C语言的创始人是谁?
丹尼斯·里奇。
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 中静态变量的用途是什么?
以下是静态变量的用途:
- 声明为静态的变量称为静态变量。 静态变量在多个函数调用之间保留其值。
- 使用静态变量是因为静态变量的作用域在整个程序中都是可用的。因此,我们可以在程序的任何位置访问静态变量。
- 静态变量最初初始化为零。如果我们更新变量的值,则分配更新的值。
- 静态变量用作所有方法共享的公共值。
- 静态变量在内存堆中只初始化一次,以减少内存使用。
10.C中的函数有什么用?
C 函数的用途是:
- C 函数用于避免在我们的程序中一次又一次地重写相同的代码。
- C 函数可以从我们程序的任何位置调用任意次数。
- 当一个程序被分成功能时,我们程序的任何部分都可以很容易地被跟踪。
- C 函数提供了可重用性概念,即将大任务分解为小任务,从而使 C 程序更易于理解。
11. C 中按值传参和按引用传参有什么区别?
以下是按值调用和按引用调用之间的区别:
- | 值传参 | 引用传参 |
---|---|---|
描述 | 当将值的副本传递给函数时,不会修改原始值。 | 当值的副本传递给函数时,原始值会被修改。 |
内存位置 | 实际参数和形式参数在不同的内存位置创建。 | 实际参数和形式参数在相同的内存位置创建。 |
安全 | 在这种情况下,实际参数仍然是安全的,因为它们不能被修改。 | 在这种情况下,实际参数不可靠,因为它们被修改。 |
参数 | 实际参数的副本被传递给形式参数。 | 实际参数的地址被传递给它们各自的形式参数。 |
按值传参的示例:
#include <stdio.h>
void change(int,int);
int main()
{
int a=10,b=20;
change(a,b); //calling a function by passing the values of variables.
printf("Value of a is: %d",a);
printf("\n");
printf("Value of b is: %d",b);
return 0;
}
void change(int x,int y)
{
x=13;
y=17;
}
输出:
Value of a is: 10
Value of b is: 20
引用传参示例:
#include <stdio.h>
void change(int*,int*);
int main()
{
int a=10,b=20;
change(&a,&b); // calling a function by passing references of variables.
printf("Value of a is: %d",a);
printf("\n");
printf("Value of b is: %d",b);
return 0;
}
void change(int *x,int *y)
{
*x=13;
*y=17;
}
输出:
Value of a is: 13
Value of b is: 17
12.C 中的递归是什么?
当一个函数调用自身时,这个过程称为递归。调用自身的函数称为递归函数。
递归函数分为两个阶段:
- 缠绕阶段
- 展开阶段
缠绕阶段:当递归函数调用自身时,达到条件时该阶段结束。
展开阶段:当条件达到时开始展开阶段,控制返回到原来的调用。
递归示例
#include <stdio.h>
int calculate_fact(int);
int main()
{
int n=5,f;
f=calculate_fact(n); // calling a function
printf("factorial of a number is %d",f);
return 0;
}
int calculate_fact(int a)
{
if(a==1)
{
return 1;
}
else
return a*calculate_fact(a-1); //calling a function recursively.
}
输出:
factorial of a number is 120
13. C 中的数组是什么?
数组是一组相似类型的元素。它有一个连续的内存位置。它使代码优化,易于遍历和易于排序。数组的大小和类型在声明后不能更改。
数组有两种类型:
- 一维数组:一维数组是一种将元素一个接一个地存储起来的数组。
句法:
data_type array_name[size];
- 多维数组:多维数组是包含多个数组的数组。
句法:
data_type array_name[size];
数组示例:
#include <stdio.h>
int main()
{
int arr[5]={1,2,3,4,5}; //an array consists of five integer values.
for(int i=0;i<5;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
输出:
1 2 3 4 5
14. C 中的指针是什么?
指针是指向值地址的变量。它使代码优化并提高性能。每当在程序中声明变量时,系统都会为变量分配一些内存。内存包含一些地址编号。保存此地址编号的变量称为指针变量。
例如:
Data_type *p;
上面的语法告诉 p 是一个指针变量,它保存给定数据类型值的地址编号。 指针示例:
#include <stdio.h>
int main()
{
int *p; //pointer of type integer.
int a=5;
p=&a;
printf("Address value of 'a' variable is %u",p);
return 0;
}
输出:
Address value of 'a' variable is 428781252
15. C 中指针的用法是什么?
- 访问数组元素:指针用于遍历整数和字符串数组。该字符串是一个以空字符“\0”结尾的字符数组。
- 动态内存分配:指针用于在程序执行期间分配和释放内存。
- 通过引用调用:指针用于将变量的引用传递给其他函数。
- 树、图、链表等数据结构:指针用于构造不同的数据结构,如树、图、链表等。
16. C 中的 NULL 指针是什么?
不指向任何值地址但 NULL 的指针称为 NULL 指针。当我们为任何类型的指针分配一个“0”值时,它就变成了一个空指针。
17. C 中的远指针是什么?
可以访问 RAM 的所有 16 个段(整个驻留内存)的指针称为远指针。远指针是一个 32 位的指针,它在给定的部分中获取内存之外的信息。
18. C 中的悬空指针是什么?
- 如果一个指针指向任何内存位置,但同时另一个指针删除了第一个指针占用的内存,而第一个指针仍然指向该内存位置,则第一个指针将被称为悬空指针。这个问题被称为悬空指针问题。
- 当一个对象被删除而不修改指针的值时,就会出现悬空指针。指针指向释放的内存。
让我们通过一个例子来了解这一点。
#include<stdio.h>
void main()
{
int *ptr = malloc(constant value); //allocating a memory space.
free(ptr); //ptr becomes a dangling pointer.
}
在上面的示例中,最初将内存分配给指针变量 ptr,然后从指针变量中释放内存。现在,指针变量,即 ptr 变成了一个悬空指针。
如何解决空指针的问题
空指针的问题可以通过为空指针分配 NULL 值来解决。
让我们通过一个例子来理解这一点:
#include<stdio.h>
void main()
{
int *ptr = malloc(constant value); //allocating a memory space.
free(ptr); //ptr becomes a dangling pointer.
ptr=NULL; //Now, ptr is no longer a dangling pointer.
}
在上面的例子中,在从指针变量中释放内存后,ptr 被赋值为 NULL 值。这意味着 ptr 不指向任何内存位置。因此,它不再是一个空指针。
19. C 中的指针是什么?
在指针概念的情况下,一个指针指向另一个指针的地址。指向指针的指针是一个指针链。通常,指针包含变量的地址。指向指针的指针包含第一个指针的地址。
我们通过一个例子来理解这个概念:
#include <stdio.h>
int main()
{
int a=10;
int *ptr,**pptr; // *ptr is a pointer and **pptr is a double pointer.
ptr=&a;
pptr=&ptr;
printf("value of a is:%d",a);
printf("\n");
printf("value of *ptr is : %d",*ptr);
printf("\n");
printf("value of **pptr is : %d",**pptr);
return 0;
}
在上面的例子中,pptr 是一个双指针,指向 ptr 变量的地址,ptr 指向 ‘a’ 变量的地址。
20. 什么是静态内存分配?
- 在静态内存分配的情况下,内存是在编译时分配的,在执行程序时不能增加内存。
- 它在数组中使用。 静态内存中变量的生命周期就是程序的生命周期。
- 静态内存是使用 static 关键字分配的。
- 静态内存使用堆栈或堆来实现。
- 需要指针来访问静态内存中存在的变量。
- 静态内存比动态内存快。
- 在静态内存中,需要更多的内存空间来存储变量。
For example:
int a[10];
上面的例子创建了一个整数类型的数组,数组的大小是固定的,即10。
- 什么是动态内存分配?
- 在动态内存分配的情况下,内存在运行时分配,并且可以在执行程序时增加内存。
- 它用于链表。
- 在运行时分配内存需要 malloc() 或calloc()函数。
- 内存的分配或释放是在程序执行时完成的。
- 访问内存不需要动态指针。
- 动态内存是使用数据段实现的。
- 存储变量所需的内存空间更少。
For example
int *p= malloc(sizeof(int)*10);
上面的例子在运行时分配内存。
22. C 语言中动态内存分配使用了哪些函数?
1.malloc() :
- malloc() 函数用于在程序执行期间分配内存。
- 它不初始化内存而是携带垃圾值。
- 如果它不能分配请求的空间,它返回一个空指针。
语法
ptr = (cast-type*) malloc(byte-size) // allocating the memory using malloc() function.
2.calloc() :calloc() 与 malloc() 函数相同,区别仅在于它用零值初始化内存。
语法:
ptr = (cast-type*)calloc(n, element-size);// allocating the memory using calloc() function.
3.realloc() :realloc() 函数用于将内存重新分配到新大小。如果内存中没有足够的可用空间,则分配新块以容纳现有数据。
语法:
ptr = realloc(ptr, newsize); // updating the memory size using realloc() function.
在上面的语法中,ptr 被分配了一个新的大小。
4.free():free() 函数释放由 calloc() 或 malloc() 函数分配的内存。
语法:
free(ptr); // memory is released using free() function.
上述语法从指针变量 ptr 释放内存。
23. malloc() 和 calloc() 有什么区别?
- | calloc() | calloc() |
---|---|---|
描述 | malloc() 函数分配单个请求内存块。 | calloc() 函数分配多个请求的内存块。 |
初始化 | 它将内存的内容初始化为零。 | 它不初始化内存的内容,所以它携带垃圾值。 |
参数数量 | 它由两个参数组成。 | 它只包含一个参数。 |
返回值 | 它返回一个指向分配内存的指针。 | 它返回一个指向分配内存的指针。 |
24. 结构体是什么?
- 该结构是一种用户定义的数据类型,允许在单个单元中存储多种类型的数据。
- 它占据了所有成员的记忆总和。结构成员只能通过结构变量访问。
- 访问相同结构的结构变量,但为每个变量分配的内存会有所不同。
结构体的语法:
struct structure_name
{
Member_variable1;
Member_variable2
.
.
}[structure variables];
让我们看一个简单的例子。
#include <stdio.h>
struct student
{
char name[10]; // structure members declaration.
int age;
}s1; //structure variable
int main()
{
printf("Enter the name");
scanf("%s",s1.name);
printf("\n");
printf("Enter the age");
scanf("%d",&s1.age);
printf("\n");
printf("Name and age of a student: %s,%d",s1.name,s1.age);
return 0;
}
输出:
Enter the name shikha
Enter the age 26
Name and age of a student: shikha,26
25. 什么是联合体?
- 联合体是一种用户定义的数据类型,允许在单个单元中存储多种类型的数据。但是,它并不占用所有成员的内存总和。它只保存最大成员的内存。
- 在联合体中,我们一次只能访问一个变量,因为它为联合的所有成员分配了一个公共空间。
语法:
union union_name
{
Member_variable1;
Member_variable2;
.
.
Member_variable n;
}[union variables];
让我们看一个简单的例子:
#include<stdio.h>
union data
{
int a; //union members declaration.
float b;
char ch;
};
int main()
{
union data d; //union variable.
d.a=3;
d.b=5.6;
d.ch='a';
printf("value of a is %d",d.a);
printf("\n");
printf("value of b is %f",d.b);
printf("\n");
printf("value of ch is %c",d.ch);
return 0;
}
输出:
value of a is 1085485921
value of b is 5.600022
value of ch is a
26. C 中的 auto 关键字是什么?
在 C 中,函数的每个局部变量都称为自动(auto)变量。在功能块内声明的变量称为局部变量。局部变量也称为自动变量。在变量的数据类型之前使用 auto 关键字是可选的。如果没有值存储在局部变量中,则它由垃圾值组成。
27. sprintf() 函数的目的是什么?
sprintf() 代表“字符串打印”。 sprintf() 函数不会在控制台屏幕上打印输出。它将数据传输到缓冲区。它返回字符串中存在的字符总数。
语法:
int sprintf ( char * str, const char * format, ... );
例子:
#include<stdio.h>
int main()
{
char a[20];
int n=sprintf(a,"javaToint");
printf("value of n is %d",n);
return 0;}
输出:
value of n is 9
28. 我们可以编译没有 main() 函数的程序吗?
是的,我们可以编译,但不能执行。 但是,如果我们使用#define,我们可以在不使用 main() 函数的情况下编译和运行 C 程序。
例如:
#include<stdio.h>
#define start main
void start() {
printf("Hello");
}
29. 什么是token?
token是一个标识符。它可以是常量、关键字、字符串文字等。标记是程序中最小的单个单元。 C 有以下标记:
- 标识符:标识符是指变量的名称。
- 关键字:关键字是编译器解释的预定义词。
- 常量:常量是在程序执行过程中不能改变的固定值。
- 运算符:运算符是执行特定操作的符号。
- 特殊字符:除字母和数字外的所有字符都被视为特殊字符。
30. 什么是命令行参数?
执行程序时传递给 main() 函数的参数称为命令行参数。
例如:
main(int count, char *args[]){
//code to be executed
}
31. ANSI 的首字母缩写词是什么?
ANSI 代表“美国国家标准协会”。它是一个维护广泛学科的组织,包括摄影胶片、计算机语言、数据编码、机械部件、安全等。
32. getch() 和 getche() 有什么区别?
getch() 函数从键盘读取单个字符。它不使用任何缓冲区,因此输入的数据不会显示在输出屏幕上。 getche() 函数从关键字读取单个字符,但数据显示在输出屏幕上。按 Alt+f5 查看输入的字符。
例子:
#include<stdio.h>
#include<conio.h>
int main()
{
char ch;
printf("Enter a character ");
ch=getch(); // taking an user input without printing the value.
printf("\nvalue of ch is %c",ch);
printf("\nEnter a character again ");
ch=getche(); // taking an user input and then displaying it on the screen.
printf("\nvalue of ch is %c",ch);
return 0;
}
输出:
Enter a character
value of ch is a
Enter a character again a
value of ch is a
在上面的示例中,通过 getch() 函数输入的值不会显示在屏幕上,而通过 getche() 函数输入的值会显示在屏幕上。
33. 什么是换行符转义序列?
新行转义序列由“\n”表示。它在输出屏幕上插入一个新行。
34. 近、远和大指针之间有什么区别?
虚拟地址由选择器和偏移量组成。 Near 指针没有显式选择器,而 far 和巨大指针具有显式选择器。对远指针进行指针运算时,选择器不会被修改,但如果是大指针,则可以修改它。 这些是非标准关键字和特定于实现的关键字。这些在现代平台中是无关紧要的。
35. 标识符的最大长度是多少?
理想情况下它是 32 个字符,但特定于实现。
36. 什么是类型转换?
类型转换是将一种数据类型转换为另一种数据类型的过程,称为类型转换。如果我们要将浮点类型值存储为 int 类型,那么我们将显式地将数据类型转换为另一种数据类型。
语法:
(type_name) expression;
37. C 语言中打开和关闭文件的函数有哪些?
fopen() 函数用于打开文件,而 fclose() 用于关闭文件。
38. 我们可以使用 C 语言中的指针访问数组吗?
是的,通过将数组的基地址保存到指针中,我们可以使用指针访问数组。
39. 什么是无限循环?
无限次连续运行的循环称为无限循环。
无限循环:
for(;;){
//code to be executed
}
无限While循环:
while(1){
//code to be executed
}
无限 Do-While 循环:
do{
//code to be executed
}while(1);