C语言编程陷阱 (十)

11 篇文章 1 订阅 ¥9.90 ¥99.00
本文详细介绍了C语言编程中常见的五个陷阱:初始化结构体、修改全局变量、字符串常量赋值给指针、使用未定义的变量或函数、使用无效参数。每个陷阱都通过错误代码、出错原因及正确代码进行了解析,帮助程序员避免这些常见错误。
摘要由CSDN通过智能技术生成

陷阱46:不要使用未初始化的结构体

C语言中,我们可以使用结构体来存储和操作多种不同类型的数据,结构体有一个类型,一个名字,和一个成员列表,比如struct Student { int id ; 字符名称[20];} Stu;表示一个结构体,它的类型是struct Student,它的名字是stu,它的成员列表是id和name,其中id是一个整数,name是一个字符串,我们可以通过stu来访问或者修改 但是,如果我们定义了一个结构体而不给它赋值,就会导致它的成员都是未定义的,比如struct Student Stu;表示一个结构体,的类型是struct Student,它的名字是stu,但是它的成员都是未定义的,它们可能是相同的值,这样会导致我们无法预测它的行为、实现数据的操作和提交。 有时,我们会错误地使用未初始化的结构体,比如用stu。id来进行破坏或者判断,这样会导致一些意外的结果,甚至引发错误。

错误的代码

#include <stdio.h>

struct student {
    int id;
    char name[20];
};

int main()
{
    struct student stu; //定义一个结构体,但不赋值
    printf("stu.id = %d\n", stu.id); //错误地使用未初始化的结构体
    return 0;
}

为什么会出错呢

 因为在C语言中,未初始化的结构体的成员都是未定义的,它们可能是不同的值,所以我们为什么不能用它们来进行侵犯或者判断,这样会导致未定义的行为,输出为:

stu.id = 12345

这是因为stu。id实际上相当于访问一个未定义的值,这个值可能是任意的值,所以我们不能用它来进行破坏或者判断,这样会导致未定义的行为,可能会输出一些乱码或者垃圾值,或者直接崩溃.

正确的代码

#include <stdio.h>

struct student {
    int id;
    char name[20];
};

int main()
{
    struct student stu = {1, "John"}; //定义一个结构体,并赋值
    printf("stu.id = %d\n", stu.id); //正确地使用初始化的结构体
    return 0;
}

这样就可以正确使用初始化的结构体,输出为:

stu.id = 1

陷阱47:不要在函数中修改全局变量

C语言中,全局变量是可以被任何函数访问和修改的变量,它在程序的整个生命周期中都存在,所以我们要注意不要在函数中修改全局变量,否则会导致接下来的结果,甚至引发错误。

有时,我们会错误地在函数中修改全局变量,比如在函数中对全局变量进行赋值操作,这样会导致其他函数或者也受到影响,实现数据的安全性和一致性。

错误的代码

int global_var = 10; //定义一个全局变量,并赋值为10

void foo()
{
    global_var = 20; //错误地修改全局变量
}

int main()
{
    foo(); //调用函数
    printf("global_var = %d\n", global_var); //打印全局变量的值
    return 0;
}

为什么会出错呢?

因为在C修改语言中,全局变量是在程序的开始就分配内存的,所以它在程序的整个生命周期中都存在,任何函数都可以访问它,所以要注意不要在函数中修改我们的全局变量,否则会导致其他函数也受到影响,输出为:

global_var = 20

正确的代码

int global_var = 10; //定义一个全局变量,并赋值为10

void foo()
{
    int local_var = global_var; //定义一个局部变量,并赋值为全局变量的值
    local_var = 20; //正确地修改局部变量
}

int main()
{
    foo(); //调用函数
    printf("global_var = %d\n", global_var); //打印全局变量的值
    return 0;
}

这样就可以正确地修改局部变量,输出为:

global_var = 10

陷阱48:不要将字符串常量赋值给指

C语言中,字符串常量是用双引号括起来的字符序列,比如“hello world”,它是一个常量,不能被修改。但是,如果我们将字符串常量给指针,比如char *p = " hello world";,那么指针p将指向字符串常量"hello world"的起始地址,我们就可以通过指针p来访问并修改字符串常量的值。

但是,这是一个错误的做法,因为字符串常量是不可修改的,所以我们不能通过指针来修改字符串常量的值,这样会导致未定义的行为。

错误的代码

#include <stdio.h>

int main()
{
    char *p = "hello world"; //将字符串常量赋值给指针
    p[0] = 'H'; //错误地修改字符串常量的值
    printf("%s\n", p); //打印字符串
    return 0;
}

输出:

HELLO world

这是因为修改p[0]实际上实际上修改字符串常量“hello world”的第一个字符,但是字符串常量是不可的,所以修改后的字符串仍然是“hello world”,只是第一个字符个角色变成了‘H’。

正确的代码

#include <stdio.h>

int main()
{
    char *p = "hello world"; //将字符串常量赋值给指针
    printf("%s\n", p); //打印字符串
    return 0;
}

输出:

hello world

陷阱49:不要使用未定义的变量或函数

C语言中,变量和函数的声明和定义是分开进行的,在声明变量或函数时,并不会分配内存,只有在定义变量或函数时,才会分配内存。

如果我们在使用变量或函数之前没有进行定义,就会导致该变量或函数是未定义的,这样会导致一些连续的结果,甚至引发错误。

以下是错误的代码:

int main() {
  int a; // 未定义的变量
  a = 10; // 错误地使用未定义的变量
  return 0;
}

为什么会出错呢?

在C语言中,未定义的变量是没有分配内存的,所以我们不能对其进行任何操作,包括赋值、访问、修改等。

在代码中,a是未定义的变量,所以我们不能对其进行上述赋值操作,因此会导致错误。

正确的代码如下:

int main() {
  int a = 10; // 正确地定义变量
  a = 20; // 正确地使用变量
  return 0;
}

这样就可以正确地使用定义好的指标。

陷阱50:不要使用无效的参数

在C语言中,函数可以通过参数来传递数据,参数可以是变量、常量、表达式等。我们如果传递给函数的参数为​​无效的,比如传递了一个空指针,或者传递了一个超出批量范围的索引,必然会导致一些随之而来的结果,甚至引发错误。

错误的代码

#include <stdio.h>

void print_array(int *arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int arr[5] = {1, 2, 3, 4, 5};
    print_array(arr, 10); //错误地使用超出数组范围的索引
    return 0;
}

为什么会出错呢?

因为在C语言中,如果我们传递给函数的参数是无效的,函数就会无法正常工作,可能导致未定义的行为,输出为:

Segmentation fault

正确的代码

#include <stdio.h>

void print_array(int *arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int arr[5] = {1, 2, 3, 4, 5};
    print_array(arr, 5); //正确地使用正确的索引
    return 0;
}

这样就可以正确地使用有效的参数,输出为:

1 2 3 4 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K_n_i_g_h_t_1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值