C语言常见面试题:基础概念

C语言作为系统编程和嵌入式开发的重要语言,在技术面试中经常出现。本文系统整理了C语言基础概念相关的常见面试题,帮助求职者全面掌握核心知识点。

1. 数据类型与变量

1.1 基本数据类型

面试题1:C语言有哪些基本数据类型?各占多少字节?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include <float.h>

// 数据类型大小演示
void demonstrate_data_types(void) {
printf("=== C语言基本数据类型 ===\n");

// 整型
printf("整型数据类型:\n");
printf("char: %zu字节, 范围: %d ~ %d\n",
sizeof(char), CHAR_MIN, CHAR_MAX);
printf("short: %zu字节, 范围: %d ~ %d\n",
sizeof(short), SHRT_MIN, SHRT_MAX);
printf("int: %zu字节, 范围: %d ~ %d\n",
sizeof(int), INT_MIN, INT_MAX);
printf("long: %zu字节, 范围: %ld ~ %ld\n",
sizeof(long), LONG_MIN, LONG_MAX);
printf("long long: %zu字节\n", sizeof(long long));

// 无符号整型
printf("\n无符号整型:\n");
printf("unsigned char: %zu字节, 范围: 0 ~ %u\n",
sizeof(unsigned char), UCHAR_MAX);
printf("unsigned short: %zu字节, 范围: 0 ~ %u\n",
sizeof(unsigned short), USHRT_MAX);
printf("unsigned int: %zu字节, 范围: 0 ~ %u\n",
sizeof(unsigned int), UINT_MAX);
printf("unsigned long: %zu字节, 范围: 0 ~ %lu\n",
sizeof(unsigned long), ULONG_MAX);

// 浮点型
printf("\n浮点型:\n");
printf("float: %zu字节, 精度: %d位, 范围: %e ~ %e\n",
sizeof(float), FLT_DIG, FLT_MIN, FLT_MAX);
printf("double: %zu字节, 精度: %d位, 范围: %e ~ %e\n",
sizeof(double), DBL_DIG, DBL_MIN, DBL_MAX);
printf("long double: %zu字节\n", sizeof(long double));

// 指针
printf("\n指针类型:\n");
printf("void*: %zu字节\n", sizeof(void*));
printf("int*: %zu字节\n", sizeof(int*));
printf("char*: %zu字节\n", sizeof(char*));

// 布尔型(C99)
printf("\n布尔型:\n");
printf("_Bool: %zu字节\n", sizeof(_Bool));

// 固定宽度整型(C99)
printf("\n固定宽度整型:\n");
printf("int8_t: %zu字节\n", sizeof(int8_t));
printf("int16_t: %zu字节\n", sizeof(int16_t));
printf("int32_t: %zu字节\n", sizeof(int32_t));
printf("int64_t: %zu字节\n", sizeof(int64_t));
}

// 数据类型转换示例
void demonstrate_type_conversion(void) {
printf("\n=== 数据类型转换 ===\n");

// 隐式转换
int i = 10;
float f = i; // int转float
double d = f; // float转double

printf("隐式转换:\n");
printf("int %d -> float %.2f -> double %.2f\n", i, f, d);

// 显式转换
double pi = 3.14159;
int truncated = (int)pi; // 截断小数部分

printf("\n显式转换:\n");
printf("double %.5f -> int %d (截断)\n", pi, truncated);

// 整型提升
char c1 = 100;
char c2 = 50;
int result = c1 + c2; // char自动提升为int

printf("\n整型提升:\n");
printf("char %d + char %d = int %d\n", c1, c2, result);

// 有符号与无符号转换
int signed_val = -1;
unsigned int unsigned_val = signed_val;

printf("\n有符号与无符号转换:\n");
printf("signed int %d -> unsigned int %u\n", signed_val, unsigned_val);

// 溢出示例
unsigned char max_char = 255;
unsigned char overflow = max_char + 1;

printf("\n溢出示例:\n");
printf("unsigned char 255 + 1 = %u (溢出)\n", overflow);
}

面试题2:什么是整型提升?什么情况下会发生?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 整型提升详细示例
void demonstrate_integer_promotion(void) {
printf("=== 整型提升示例 ===\n");

// 示例1:char和short的运算
char c1 = 10, c2 = 20;
short s1 = 100, s2 = 200;

// 在运算中,char和short会提升为int
printf("char运算:\n");
printf("sizeof(c1) = %zu, sizeof(c1 + c2) = %zu\n",
sizeof(c1), sizeof(c1 + c2));

printf("short运算:\n");
printf("sizeof(s1) = %zu, sizeof(s1 + s2) = %zu\n",
sizeof(s1), sizeof(s1 + s2));

// 示例2:位运算中的提升
unsigned char uc = 0xFF;
printf("\n位运算提升:\n");
printf("~uc = 0x%X (提升为int后取反)\n", ~uc);

// 示例3:三元运算符中的提升
char result = (1 > 0) ? c1 : s1;
printf("\n三元运算符:\n");
printf("sizeof(result) = %zu, sizeof((1>0)?c1:s1) = %zu\n",
sizeof(result), sizeof((1 > 0) ? c1 : s1));
}

1.2 存储类别

面试题3:C语言有哪些存储类别?它们的区别是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>

// 全局变量(外部链接)
int global_var = 100;

// 静态全局变量(内部链接)
static int static_global = 200;

// 外部声明
extern int external_var;

// 存储类别演示
void demonstrate_storage_classes(void) {
printf("=== 存储类别演示 ===\n");

// auto存储类别(默认)
auto int auto_var = 10;
int local_var = 20; // 等同于auto int local_var

printf("局部变量(auto):\n");
printf("auto_var = %d, local_var = %d\n", auto_var, local_var);

// static局部变量
static int static_local = 0;
static_local++;

printf("\n静态局部变量:\n");
printf("static_local = %d (保持值)\n", static_local);

// register变量(建议)
register int reg_var = 30;

printf("\nregister变量:\n");
printf("reg_var = %d\n", reg_var);
// printf("&reg_var = %p\n", &reg_var); // 错误:不能取register变量地址

// 全局变量访问
printf("\n全局变量:\n");
printf("global_var = %d\n", global_var);
printf("static_global = %d\n", static_global);
}

// 静态函数(内部链接)
static void static_function(void) {
printf("这是一个静态函数\n");
}

// 函数中的静态变量
void counter_function(void) {
static int count = 0; // 只初始化一次
count++;
printf("函数调用次数: %d\n", count);
}

// 存储类别生命周期演示
void demonstrate_variable_lifetime(void) {
printf("\n=== 变量生命周期 ===\n");

// 调用多次查看静态变量行为
for (int i = 0; i < 3; i++) {
counter_function();
}

// 局部变量每次都重新初始化
for (int i = 0; i < 3; i++) {
int local = 0;
local++;
printf("局部变量 local = %d\n", local);
}
}

面试题4:static关键字的作用是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// static关键字的多种用法

// 1. 静态全局变量(限制作用域到当前文件)
static int file_scope_var = 42;

// 2. 静态函数(限制作用域到当前文件)
static int add_numbers(int a, int b) {
return a + b;
}

// 3. 静态局部变量演示
void static_local_demo(void) {
static int call_count = 0; // 只初始化一次
static int sum = 0; // 保持上次的值

call_count++;
sum += call_count;

printf("第%d次调用,累计和: %d\n", call_count, sum);
}

// 4. 静态数组初始化
void static_array_demo(void) {
static int arr[5] = {1, 2, 3, 4, 5}; // 静态初始化
static char str[] = "Hello"; // 静态字符串

printf("静态数组: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n静态字符串: %s\n", str);
}

// 5. 静态变量的内存分配
void memory_allocation_demo(void) {
printf("\n=== 内存分配演示 ===\n");

int local_var = 10; // 栈上分配
static int static_var = 20; // 数据段分配

printf("局部变量地址: %p\n", (void*)&local_var);
printf("静态变量地址: %p\n", (void*)&static_var);
printf("全局变量地址: %p\n", (void*)&global_var);

// 通常静态变量和全局变量地址相近,局部变量地址差异较大
}

2. 函数与作用域

2.1 函数基础

面试题5:函数的声明和定义有什么区别?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 函数声明(原型)
int calculate_sum(int a, int b); // 完整声明
int calculate_product(int, int); // 可省略参数名
void print_array(int arr[], int size); // 数组参数
void process_data(void); // 无参数函数

// 函数定义
int calculate_sum(int a, int b) {
return a + b;
}

int calculate_product(int x, int y) {
return x * y;
}

void print_array(int arr[], int size) {
printf("数组元素: ");
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

void process_data(void) {
printf("处理数据...\n");
}

// 函数指针演示
void demonstrate_function_pointers(void) {
printf("=== 函数指针演示 ===\n");

// 声明函数指针
int (*operation)(int, int);

// 指向不同函数
operation = calculate_sum;
printf("使用函数指针调用加法: %d\n", operation(10, 20));

operation = calculate_product;
printf("使用函数指针调用乘法: %d\n", operation(10, 20));

// 函数指针数组
int (*operations[])(int, int) = {calculate_sum, calculate_product};

printf("\n函数指针数组:\n");
for (int i = 0; i < 2; i++) {
printf("操作%d结果: %d\n", i, operations[i](5, 6));
}
}

面试题6:什么是递归?递归的优缺点是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 递归示例

// 1. 阶乘计算
long long factorial(int n) {
// 基础情况
if (n <= 1) {
return 1;
}
// 递归情况
return n * factorial(n - 1);
}

// 2. 斐波那契数列
long long fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}

// 3. 优化的斐波那契(记忆化)
long long fibonacci_memo(int n, long long memo[]) {
if (n <= 1) {
return n;
}

if (memo[n] != -1) {
return memo[n]; // 已计算过
}

memo[n] = fibonacci_memo(n - 1, memo) + fibonacci_memo(n - 2, memo);
return memo[n];
}

// 4. 迭代版本的斐波那契
long long fibonacci_iterative(int n) {
if (n <= 1) {
return n;
}

long long prev = 0, curr = 1;
for (int i = 2; i <= n; i++) {
long long temp = curr;
curr = prev + curr;
prev = temp;
}
return curr;
}

// 5. 汉诺塔问题
void hanoi(int n, char from, char to, char aux) {
if (n == 1) {
printf("移动盘子从 %c 到 %c\n", from, to);
return;
}

hanoi(n - 1, from, aux, to); // 移动n-1个盘子到辅助柱
printf("移动盘子从 %c 到 %c\n", from, to); // 移动最大盘子
hanoi(n - 1, aux, to, from); // 移动n-1个盘子到目标柱
}

// 递归性能比较
void compare_recursion_performance(void) {
printf("=== 递归性能比较 ===\n");

int n = 40;

// 准备记忆化数组
long long memo[n + 1];
for (int i = 0; i <= n; i++) {
memo[i] = -1;
}

printf("计算斐波那契数列第%d项:\n", n);

// 注意:普通递归对于大数值会很慢,这里用较小值演示
if (n <= 35) {
printf("普通递归: %lld\n", fibonacci(n));
} else {
printf("普通递归: 数值过大,跳过\n");
}

printf("记忆化递归: %lld\n", fibonacci_memo(n, memo));
printf("迭代版本: %lld\n", fibonacci_iterative(n));

// 汉诺塔演示(小规模)
printf("\n汉诺塔问题(3个盘子):\n");
hanoi(3, 'A', 'C', 'B');
}

2.2 作用域和链接

面试题7:C语言的作用域规则是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// 全局作用域
int global_scope = 100;

// 文件作用域(静态全局)
static int file_scope = 200;

void demonstrate_scope_rules(void) {
printf("=== 作用域规则演示 ===\n");

// 函数作用域
int function_scope = 300;

printf("全局作用域变量: %d\n", global_scope);
printf("文件作用域变量: %d\n", file_scope);
printf("函数作用域变量: %d\n", function_scope);

// 块作用域
{
int block_scope = 400;
int function_scope = 350; // 隐藏外层同名变量

printf("\n块作用域内:\n");
printf("块作用域变量: %d\n", block_scope);
printf("隐藏的函数作用域变量: %d\n", function_scope);
printf("全局变量仍可访问: %d\n", global_scope);
}

printf("\n块作用域外:\n");
printf("函数作用域变量恢复: %d\n", function_scope);
// printf("%d\n", block_scope); // 错误:超出作用域

// for循环作用域(C99)
for (int i = 0; i < 3; i++) {
printf("循环变量 i = %d\n", i);
}
// printf("%d\n", i); // 错误:i超出作用域
}

// 变量隐藏示例
void demonstrate_variable_hiding(void) {
printf("\n=== 变量隐藏演示 ===\n");

int x = 10; // 外层x
printf("外层 x = %d\n", x);

{
int x = 20; // 内层x,隐藏外层x
printf("内层 x = %d\n", x);

{
int x = 30; // 更内层x
printf("更内层 x = %d\n", x);
}

printf("回到内层 x = %d\n", x);
}

printf("回到外层 x = %d\n", x);
}

3. 预处理器

3.1 宏定义

面试题8:#define和const的区别是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>

// 宏定义
#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
#define DEBUG_PRINT(fmt, ...) printf("[DEBUG] " fmt, ##__VA_ARGS__)

// const常量
const double PI_CONST = 3.14159;
const int MAX_SIZE = 100;

void demonstrate_define_vs_const(void) {
printf("=== #define vs const 演示 ===\n");

// 宏替换
double area1 = PI * 5 * 5;
printf("使用宏PI计算面积: %.2f\n", area1);

// const常量
double area2 = PI_CONST * 5 * 5;
printf("使用const PI计算面积: %.2f\n", area2);

// 宏函数
int max_val = MAX(10, 20);
printf("宏MAX(10, 20) = %d\n", max_val);

// 宏的副作用
int a = 5, b = 3;
int result = MAX(++a, ++b); // 危险:a或b可能被多次递增
printf("MAX(++a, ++b) = %d, a = %d, b = %d\n", result, a, b);

// 宏的字符串化
DEBUG_PRINT("变量值: %d\n", max_val);

// 类型安全比较
// PI = 3.0; // 错误:宏不能重新赋值(编译时替换)
// PI_CONST = 3.0; // 错误:const不能修改

printf("\n内存占用:\n");
printf("宏PI不占用内存(编译时替换)\n");
printf("const PI_CONST地址: %p\n", (void*)&PI_CONST);
}

// 宏的高级用法
#define STRINGIFY(x) #x
#define CONCAT(a, b) a##b
#define DECLARE_VAR(type, name) type CONCAT(var_, name)

void demonstrate_advanced_macros(void) {
printf("\n=== 高级宏用法 ===\n");

// 字符串化
printf("字符串化: %s\n", STRINGIFY(Hello World));

// 标记连接
DECLARE_VAR(int, counter) = 42;
printf("声明的变量 var_counter = %d\n", var_counter);

// 条件编译宏
#ifdef DEBUG
printf("调试模式开启\n");
#else
printf("发布模式\n");
#endif

// 预定义宏
printf("\n预定义宏信息:\n");
printf("文件: %s\n", __FILE__);
printf("行号: %d\n", __LINE__);
printf("函数: %s\n", __func__);
printf("编译日期: %s\n", __DATE__);
printf("编译时间: %s\n", __TIME__);
}

3.2 条件编译

面试题9:条件编译的作用是什么?如何使用?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 条件编译示例

// 平台相关代码
#ifdef _WIN32
#define PLATFORM "Windows"
#include <windows.h>
#elif defined(__linux__)
#define PLATFORM "Linux"
#include <unistd.h>
#elif defined(__APPLE__)
#define PLATFORM "macOS"
#include <unistd.h>
#else
#define PLATFORM "Unknown"
#endif

// 调试开关
#define DEBUG_LEVEL 2

#if DEBUG_LEVEL >= 1
#define DBG1(fmt, ...) printf("[DBG1] " fmt, ##__VA_ARGS__)
#else
#define DBG1(fmt, ...)
#endif

#if DEBUG_LEVEL >= 2
#define DBG2(fmt, ...) printf("[DBG2] " fmt, ##__VA_ARGS__)
#else
#define DBG2(fmt, ...)
#endif

// 功能开关
#define FEATURE_LOGGING 1
#define FEATURE_ENCRYPTION 0

void demonstrate_conditional_compilation(void) {
printf("=== 条件编译演示 ===\n");

printf("当前平台: %s\n", PLATFORM);

// 调试信息
DBG1("这是1级调试信息\n");
DBG2("这是2级调试信息\n");

// 功能开关
#if FEATURE_LOGGING
printf("日志功能已启用\n");
#endif

#if FEATURE_ENCRYPTION
printf("加密功能已启用\n");
#else
printf("加密功能已禁用\n");
#endif

// 编译器版本检查
#if __STDC_VERSION__ >= 199901L
printf("支持C99标准\n");
#endif

#if __STDC_VERSION__ >= 201112L
printf("支持C11标准\n");
#endif
}

// 头文件保护
#ifndef HEADER_GUARD_EXAMPLE_H
#define HEADER_GUARD_EXAMPLE_H

// 头文件内容
typedef struct {
int x, y;
} Point;

void print_point(Point p);

#endif // HEADER_GUARD_EXAMPLE_H

// 实现函数
void print_point(Point p) {
printf("Point(%d, %d)\n", p.x, p.y);
}

4. 输入输出

4.1 标准I/O

面试题10:printf和scanf的格式说明符有哪些?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <stdio.h>
#include <stdarg.h>

void demonstrate_printf_formats(void) {
printf("=== printf格式说明符演示 ===\n");

int i = 42;
unsigned int ui = 42U;
long l = 123456789L;
float f = 3.14159f;
double d = 2.718281828;
char c = 'A';
char str[] = "Hello";
void *ptr = &i;

// 整数格式
printf("整数格式:\n");
printf("%%d: %d\n", i);
printf("%%i: %i\n", i);
printf("%%u: %u\n", ui);
printf("%%o: %o\n", ui);
printf("%%x: %x\n", ui);
printf("%%X: %X\n", ui);
printf("%%ld: %ld\n", l);

// 浮点格式
printf("\n浮点格式:\n");
printf("%%f: %f\n", f);
printf("%%.2f: %.2f\n", f);
printf("%%e: %e\n", d);
printf("%%E: %E\n", d);
printf("%%g: %g\n", d);
printf("%%G: %G\n", d);

// 字符和字符串
printf("\n字符和字符串:\n");
printf("%%c: %c\n", c);
printf("%%s: %s\n", str);
printf("%%p: %p\n", ptr);

// 宽度和精度
printf("\n宽度和精度:\n");
printf("%%10d: %10d\n", i);
printf("%%-10d: %-10d|\n", i);
printf("%%010d: %010d\n", i);
printf("%%*d: %*d\n", 8, i);
printf("%%.3s: %.3s\n", str);
printf("%%10.3s: %10.3s\n", str);
}

void demonstrate_scanf_formats(void) {
printf("\n=== scanf格式说明符演示 ===\n");

// 注意:实际使用时需要用户输入,这里只演示格式
printf("scanf格式说明符:\n");
printf("%%d - 读取十进制整数\n");
printf("%%i - 读取整数(自动识别进制)\n");
printf("%%u - 读取无符号整数\n");
printf("%%f - 读取浮点数\n");
printf("%%lf - 读取double\n");
printf("%%c - 读取单个字符\n");
printf("%%s - 读取字符串(到空白符)\n");
printf("%%[...] - 读取指定字符集\n");
printf("%%[^...] - 读取非指定字符集\n");

// 示例(注释掉避免等待输入)
/*
int num;
char buffer[100];

printf("请输入一个整数: ");
scanf("%d", &num);
printf("您输入的整数是: %d\n", num);

printf("请输入一个字符串: ");
scanf("%s", buffer);
printf("您输入的字符串是: %s\n", buffer);
*/
}

// 自定义printf函数
void my_printf(const char *format, ...) {
va_list args;
va_start(args, format);

printf("[自定义] ");
vprintf(format, args);

va_end(args);
}

void demonstrate_custom_printf(void) {
printf("\n=== 自定义printf演示 ===\n");

my_printf("这是自定义printf: %d, %s\n", 42, "测试");
}

5. 综合示例

5.1 面试题综合练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// 综合面试题练习

// 题目1:实现字符串长度函数
size_t my_strlen(const char *str) {
if (!str) return 0;

size_t len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}

// 题目2:实现字符串复制函数
char* my_strcpy(char *dest, const char *src) {
if (!dest || !src) return NULL;

char *original_dest = dest;
while ((*dest++ = *src++) != '\0') {
// 复制字符直到遇到空字符
}
return original_dest;
}

// 题目3:实现整数反转函数
int reverse_integer(int num) {
int reversed = 0;
int sign = (num < 0) ? -1 : 1;
num = (num < 0) ? -num : num; // 取绝对值

while (num > 0) {
// 检查溢出
if (reversed > (INT_MAX - num % 10) / 10) {
return 0; // 溢出返回0
}
reversed = reversed * 10 + num % 10;
num /= 10;
}

return reversed * sign;
}

// 题目4:判断是否为回文数
int is_palindrome(int num) {
if (num < 0) return 0; // 负数不是回文

int original = num;
int reversed = 0;

while (num > 0) {
reversed = reversed * 10 + num % 10;
num /= 10;
}

return original == reversed;
}

// 题目5:找出数组中的最大值和最小值
void find_min_max(int arr[], int size, int *min, int *max) {
if (!arr || size <= 0 || !min || !max) {
return;
}

*min = *max = arr[0];

for (int i = 1; i < size; i++) {
if (arr[i] < *min) {
*min = arr[i];
}
if (arr[i] > *max) {
*max = arr[i];
}
}
}

// 综合测试函数
void run_interview_exercises(void) {
printf("=== 面试题综合练习 ===\n");

// 测试字符串函数
const char *test_str = "Hello, World!";
printf("字符串 \"%s\" 长度: %zu\n", test_str, my_strlen(test_str));

char buffer[50];
my_strcpy(buffer, test_str);
printf("复制结果: \"%s\"\n", buffer);

// 测试整数反转
int num = 12345;
printf("\n%d 反转后: %d\n", num, reverse_integer(num));

// 测试回文判断
int palindrome_nums[] = {121, 12321, 123, -121};
printf("\n回文数判断:\n");
for (int i = 0; i < 4; i++) {
printf("%d %s回文数\n", palindrome_nums[i],
is_palindrome(palindrome_nums[i]) ? "是" : "不是");
}

// 测试最值查找
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5};
int min, max;
find_min_max(arr, sizeof(arr)/sizeof(arr[0]), &min, &max);
printf("\n数组最小值: %d, 最大值: %d\n", min, max);
}

// 主函数
int main(void) {
printf("C语言基础概念面试题演示\n");
printf("========================\n\n");

// 数据类型演示
demonstrate_data_types();
demonstrate_type_conversion();
demonstrate_integer_promotion();

// 存储类别演示
demonstrate_storage_classes();
demonstrate_variable_lifetime();

// 函数演示
demonstrate_function_pointers();
compare_recursion_performance();

// 作用域演示
demonstrate_scope_rules();
demonstrate_variable_hiding();

// 预处理器演示
demonstrate_define_vs_const();
demonstrate_advanced_macros();
demonstrate_conditional_compilation();

// I/O演示
demonstrate_printf_formats();
demonstrate_scanf_formats();
demonstrate_custom_printf();

// 综合练习
run_interview_exercises();

return 0;
}

总结

C语言基础概念面试题涵盖了以下核心知识点:

重要概念

  1. 数据类型 - 基本类型、大小、范围、转换规则
  2. 存储类别 - auto、static、register、extern的区别
  3. 函数机制 - 声明、定义、递归、函数指针
  4. 作用域规则 - 全局、文件、函数、块作用域
  5. 预处理器 - 宏定义、条件编译、头文件保护

面试要点

  1. 理解原理 - 不仅要知道怎么用,还要知道为什么
  2. 注意细节 - 类型转换、溢出、作用域等细节问题
  3. 实践能力 - 能够编写正确、高效的代码
  4. 调试技能 - 能够发现和解决常见问题
  5. 最佳实践 - 遵循编码规范和安全原则

掌握这些基础概念是C语言编程的根基,也是技术面试中的重点考查内容。

版权所有,如有侵权请联系我