首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C 语言篇】常考易错点大盘点:吃透这些,做题少踩坑

【C 语言篇】常考易错点大盘点:吃透这些,做题少踩坑

作者头像
意疏
发布2025-08-23 08:31:16
发布2025-08-23 08:31:16
3750
举报
文章被收录于专栏:学习学习

C语言常考及易错题整理

前言:

为帮助大家更好地掌握C语言核心知识点,本文整理了常考及易错题,涵盖变量作用域、宏定义、循环控制、编程实现等多个方面,每道题均附详细解析与优化代码,助力理解与巩固。

一、选择题

  1. 全局、局部和静态变量

题目:执行下面程序,正确的输出是:

代码语言:javascript
复制
int a = 5, b = 7;
void swap()
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}
int main()
{  
    int a = 3, b = 8;  
    swap();
    printf("%d,%d\n", a, b);
    return 0;
}

答案解析: 正确答案:3,8

swap函数操作的是全局变量ab,但主函数中定义的ab是局部变量。根据“局部变量优先”原则,main函数内的输出语句使用的是局部变量,因此结果为3,8

  1. 静态局部变量

题目:如下函数的f(1)的值为:

代码语言:javascript
复制
int f(int num)
{
    static int count = 1;
    if(num >= 5)
        return num;
    num = num + count;
    count++;
    return f(num);
}

答案解析: 正确答案:7

静态局部变量count的生命周期贯穿函数多次调用,初始化仅执行一次。

  • 第一次调用:num=1+1=2count=2
  • 第二次调用:num=2+2=4count=3
  • 第三次调用:num=4+3=7,满足num≥5,返回7
  1. 全局变量与循环

题目:以下程序的输出结果为:

代码语言:javascript
复制
#include <stdio.h>
int g;
void print_star()
{
    for (g = 5; g < 8; g++)
        printf("%c", '*');
    printf("\t");
}
int main()
{
    for (g = 5; g <= 8; g++)
        print_star();
    return 0;
}

答案解析: 正确答案:*** (3个星号+1个制表符)

全局变量gmain中初始化为5,第一次调用print_star()时:

  • 循环执行g=5、6、7,输出3个*g最终变为8
  • 执行printf("\t")输出制表符 回到main后,g自增为9,不满足g≤8,循环结束,总输出为***

4.#define与typedef

题目:test.c文件中定义的四个变量中,是指针类型的为【多选】:

代码语言:javascript
复制
#define PTR_INT int*
typedef int* int_ptr;
PTR_INT x, y;
int_ptr p, q;

答案解析: 正确答案:x、p、q

  • 宏定义PTR_INT是文本替换,PTR_INT x,y;等价于int *x, y;,仅x为指针。
  • typedef定义的int_ptr是独立类型,pq均为指针。
  1. 宏替换计算

题目:以下程序结果输出是什么:

代码语言:javascript
复制
#include <stdio.h>
#define A 2
#define B A+1
#define SUM (B+1)*B/2
int main()
{
    printf("%d\n", SUM);
    return 0;
}

答案解析: 正确答案:8

宏替换仅做文本替换,SUM展开为(A+1+1)*A+1/2,代入A=2得: (2+1+1)*2 + 0 = 4*2 = 8(整数除法1/2=0)。

6.转义字符

题目:以下程序段输出结果是什么:

代码语言:javascript
复制
#include<stdio.h>
int main()
{     
    char str[] = "\\123abc\123def\t";    
    printf("%d\n", strlen(str));    
    return 0;
}

答案解析: 正确答案:11

转义字符按1个字符计算: '\\'(1)、'\123'(1)、'a'(1)、'b'(1)、'c'(1)、'\123'(1)、'd'(1)、'e'(1)、'f'(1)、'\t'(1),共11个字符。

7.复合赋值操作符

题目:下面代码段的输出是:

代码语言:javascript
复制
#include <stdio.h>
int main()
{
    int num = 3; 
    printf("%d\n", (num += num -= num * num));
    return 0;
}

答案解析: 正确答案:-12

复合赋值从右向左计算:

  1. 先执行num -= num*numnum = 3 - 3*3 = -6
  2. 再执行num += -6num = -6 + (-6) = -12

8.多层循环跳出

题目:下列跳出多层循环的做法正确的是【多选】:

A. 用return结束函数

代码语言:javascript
复制
void loop_func()
{
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            if(i==2 && j==2)
                return; // 直接结束函数
        }
    }
}

B. 修改外层循环条件

代码语言:javascript
复制
for( int i = 0 ; i < MAX1 ; i ++ ) 
{
    for( int j = 0 ; j < MAX2 ; j ++ )
    {
        if( condition )
        {
            i = MAX1; // 使外层循环失效
            break;
        }
    }
}

C. 外层循环设判断条件

代码语言:javascript
复制
int flag = 0;
for( ; flag != 1 && condition2 ; )
{
    for( ; flag != 1 && condition3 ; )
    {
        if( condition1 )
            flag = 1 ;
    }
}

D. 外层循环后加break

代码语言:javascript
复制
int flag = 0;
for( ; condition2 ; )
{
    for( ; condition3 ; )
    {
        if( condition1 )
            flag = 1 ;
    }
    if( flag == 1 )
        break ;
}

答案解析: 正确答案:ABCD

四种方法均可实现多层循环跳出:

  • A通过函数返回直接终止
  • B通过修改外层变量使条件失效
  • C、D通过标志位控制外层循环

9.循环执行次数

题目:执行下面的程序段,语句3的执行次数为:

代码语言:javascript
复制
for(i = 0; i <= n-1; i++)   // (1)
    for(j = n; j > i; j--)  // (2)
        statement;          // (3)

答案解析: 正确答案:n(n+1)/2

外循环执行n次(i=0i=n-1),内循环次数依次为n、n-1、…、1,总和为等差数列求和n+(n-1)+…+1 = n(n+1)/2

10.while循环条件

题目:对于下面说法,正确的是:

代码语言:javascript
复制
int t=0;
while(printf("*"))
{
    t++;
    if (t<3)
        break;
}

A. 循环控制表达式与0等价 B. 循环控制表达式与’0’等价 C. 循环控制表达式不合法 D. 以上说法都不对

答案解析: 正确答案:B

printf("*")返回输出字符数1(非0,循环条件为真)。'0'的ASCII码为48(非0),与循环条件等价;0为假,故B正确。

11.字符输入统计

题目:以下不能统计一行输入字符数(不含回车)的程序段是:

A. n=0;while(ch=getchar()!='\n') n++; B. n=0;while(getchar()!='\n') n++; C. for(n=0;getchar()!='\n';n++); D. n=0;for(ch=getchar();ch!='\n';n++);

答案解析: 正确答案:D

D中for循环的初始化部分仅执行一次,ch只获取一次输入,若输入非回车则陷入死循环,无法统计。

12.switch语句穿透

题目:输入ADescriptor<回车>,程序运行结果是:

代码语言:javascript
复制
#include <stdio.h>
int main()
{
    char ch;
    int v0=0,v1=0,v2=0;
    do
    {
        switch(ch=getchar())
        {
            case'a':case'A':case'e':case'E':
            case'i':case'I':case'o':case'O':
            case'u':case'U':v1 += 1;
            default:v0+=1;v2+=1;
        }
    }while(ch!='\n');
    printf("v0=%d,v1=%d,v2=%d\n",v0,v1,v2);
    return 0;
}

答案解析: 正确答案:v0=12,v1=4,v2=12

输入共11个字符+回车(循环在回车时结束)。switchbreak,匹配元音(A、e、i、o)时执行v1++后继续default;非元音直接执行default。最终v0=v2=12v1=4

13.结构体、浮点比较与数组赋值

题目:对于下面说法,正确的是:

A. struct X{short s;int i;char c;}sizeof(X)等于成员大小之和 B. 可用a == 0.0判断double变量a是否为零 C. char a[14] = "Hello, world!";char a[14]; a = "Hello, world!";效果相同 D. 以上说法都不对

答案解析: 正确答案:D

  • A错误:结构体存在内存对齐,sizeof(X)大于成员之和
  • B错误:浮点数有精度误差,不能直接用==判断
  • C错误:数组名是常量,不能直接赋值

二、编程题

1.计算日期到天数转换

题目:根据输入的年、月、日,计算是这一年的第几天(保证日期合法)。

代码实现

代码语言:javascript
复制
#include <stdio.h>
// 判断闰年:能被4整除且不能被100整除,或能被400整除
int is_leap(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int main() {
    int year, month, day;
    // 每月天数(索引0未使用,方便月份直接对应)
    int days_in_month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    printf("请输入日期(格式:YYYY MM DD):\n");
    while (scanf("%d %d %d", &year, &month, &day) == 3) {
        int total = day; // 累加当月天数
        // 闰年且月份>2时,2月多1天
        if (is_leap(year) && month > 2) {
            total += 1;
        }   
        // 累加之前所有月份的天数
        for (int i = 1; i < month; i++) {
            total += days_in_month[i];
        }  
        printf("%d\n", total);
    }
    return 0;
}

结果:

2.柯尼希定理(尼科彻斯定理)

题目:验证任何整数m的立方都可写成m个连续奇数之和,如3³=7+9+11,输入m并输出结果。

代码实现

代码语言:javascript
复制
#include <stdio.h>
int main() {
    int m;
    while (scanf("%d", &m) == 1) {
        // 起始奇数公式:m*(m-1)+1
        int start = m * (m - 1) + 1;
        printf("%d", start); // 打印第一个奇数
        // 依次打印后续m-1个奇数(每次+2)
        for (int i = 1; i < m; i++) {
            start += 2;
            printf("+%d", start);
        }
        printf("\n");
    }
    return 0;
}

3.旋转数组的最小数字

题目:给定非降序数组的旋转数组(如[3,4,5,1,2]),求其中的最小值。

代码实现

代码语言:javascript
复制
#include <stdio.h>
#include <limits.h>
int findMin(int* nums, int numsSize) {
    int left = 0, right = numsSize - 1;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] > nums[right]) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return nums[left];
}
int main() {
    int n;
    printf("请输入数组的长度:");
    scanf("%d", &n);
    int nums[n];
    printf("请输入旋转后的非降序数组元素(用空格分隔):");
    for (int i = 0; i < n; i++) {
        scanf("%d", &nums[i]);
    }
    int min = findMin(nums, n);
    printf("数组中的最小值是:%d\n", min);
    return 0;
}

通过以上题目练习,可加深对C语言核心概念的理解,尤其注意变量作用域、宏特性、循环控制等易混淆点。编程题需注重逻辑梳理与边界处理,提升代码健壮性。 你好,我是意疏。我们一起进步。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C语言常考及易错题整理
    • 一、选择题
    • 二、编程题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档