• C语言编程常见错误


    列举一些C语言编程常见的错误,这些错误比较隐蔽,比较难发现。程序可以正常运行,但无法获得正确的结果

    变量未赋初始值

    #include 
    
    int calSum(int sum);
    
    int main(void) {
        int sum,sum0,sum1,sum2;		// 第6行
        printf("初始值 %d %d %d %d\n", sum, sum0, sum1, sum2);
        printf("计算结果 %d %d %d %d\n", calSum(sum), calSum(sum0), calSum(sum1), calSum(sum2));
        return 0;
    }
    
    int calSum(int sum) {
        for (int i = 0; i < 10; i++) {
            sum = sum + i;
        }
        return sum;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第6行的变量未赋初始值,它的默认值是0吗?
    运行结果如下

    初始值 0 4199705 0 8
    计算结果 45 4199750 45 53
    
    • 1
    • 2

    不同的编译器运行结果可能不同。可以看出有些的初始值是0,有些初始值不是0。错误在编译阶段发现不了,运行的时候有时也是正确的,有些情况是错误的

    数组越界

    #include 
    
    #define SIZE 10
    
    int main(void) {
        int arr[SIZE] = {1,2,3,4,5,6,7,8,9,10};
        for (int i = SIZE; i <= SIZE + 5; i++) {
            arr[i] = 20;
        }
        for (int i = 0; i <= SIZE + 5; i++) {
            printf("arr[%d] is %d\n", i, arr[i]);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上面的代码编译、运行都不会报错。C语言不会检查数组越界的问题,超过了索引还是可以设置值,但是输出的值却不正确,结果如下

    arr[0] is 1
    arr[1] is 2
    arr[2] is 3
    arr[3] is 4
    arr[4] is 5
    arr[5] is 6
    arr[6] is 7
    arr[7] is 8
    arr[8] is 9
    arr[9] is 10
    arr[10] is 10
    arr[11] is 21
    arr[12] is 10491360
    arr[13] is 0
    arr[14] is 4199367
    arr[15] is 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    可以看到超过索引之后的赋值,取出来的数据都是错误的。

    case 之后没有 break;

    #include 
    
    int main(void) {
        int arr[3] = {1,2,3};
        for (int i = 0; i < 3; i++) {
            printf("arr[%d] = %d\n", i, arr[i]);
            switch (arr[i]) {
                case 1:
                    printf("match case 1\n");
                case 2:
                    printf("match case 2\n");
                case 3:
                    printf("match case 3\n");
                default:
                    printf("match default\n");
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    代码片段中没有 break, 当匹配到某个 case 之后,在这个 case之后的输出都会执行,执行结果如下

    arr[0] = 1
    match case 1
    match case 2
    match case 3
    match default
    arr[1] = 2
    match case 2
    match case 3
    match default
    arr[2] = 3
    match case 3
    match default
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    修改上面的代码片段,加上 break 之后,看看运行结果

    #include 
    
    int main(void) {
        int arr[3] = {1,2,3};
        for (int i = 0; i < 3; i++) {
            printf("arr[%d] = %d\n", i, arr[i]);
            switch (arr[i]) {
                case 1:
                    printf("match case 1\n");
                    break;
                case 2:
                    printf("match case 2\n");
                    break;
                case 3:
                    printf("match case 3\n");
                    break;
                default:
                    printf("match default\n");
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    再次运行,结果如下

    arr[0] = 1
    match case 1
    arr[1] = 2
    match case 2
    arr[2] = 3
    match case 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    if、else 没有加花括号

    if 没有加花括号

    #include 
    
    int main(void) {
        for (int i = 0; i < 3; i++) {
            if (i >= 2)
                printf("%d >= 2\n", i);
                printf("%d 大于或等于 2\n", i);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面的代码片段,期望得到的结果是

    2 >= 2
    2 大于或等于 2
    
    • 1
    • 2

    实际运行的结果如下:

    0 大于或等于 2
    1 大于或等于 2
    2 >= 2
    2 大于或等于 2
    
    • 1
    • 2
    • 3
    • 4

    由于 if 没有加 括号,那么这个if 的作用域到 ; 结束。
    修改程序为如下,就可以得到预期的结果

    #include 
    
    int main(void)
    {
        for (int i = 0; i < 3; i++)
        {
            if (i >= 2)
            {
                printf("%d >= 2\n", i);
                printf("%d 大于或等于 2\n", i);
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    两条输出语句都在 if 的花括号里面,都属于这个 if 的作用域

    if-else 都没加花括号

    #include 
    
    int main(void)
    {
        for (int i = 0; i < 3; i++)
        {   
            if (i >= 1) 
                if (i >= 2)
                    printf("%d >= 2\n", i);
            else
                printf("%d < 1\n", i);
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    else 与 那个 if 匹配?
    运行结果如下

    1 < 1
    2 >= 2
    
    • 1
    • 2

    从运行结果看,else 与 if (i >= 2) 匹配了,与最近的 if 匹配了,并不是按照缩进对齐的,if、else 都加上花括号就正确了

    #include 
    
    int main(void)
    {
        for (int i = 0; i < 3; i++)
        {
            if (i >= 1)
            {
                if (i >= 2)
                {
                    printf("%d >= 2\n", i);
                }
            }
            else
            {
                printf("%d < 1\n", i);
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    IDEA调试总结
    CSP2022
    vscode配置conda环境
    BeanPostProcessor(Spring后置处理器)如何使用呢?
    CPDA|如何拥有数据分析思维?
    如何将DHTMLX Suite集成到Scheduler Lightbox中?让项目管理更可控!
    【优化算法】基于matlab融合飞行机制的粒子群优化算法【含Matlab源码 1924期】
    Docker知识总结 (六) Docker网络
    6种自媒体赚钱方法!
    神经网络图片怎么分类的,图神经网络怎么做分类
  • 原文地址:https://blog.csdn.net/modelmd/article/details/128140246