当前位置: 首页 > article >正文

C语言编程陷阱 (九)

陷阱41:不要使用内存下标越界

C语言中,集群的下标可能是从0开始的,比如集群的长度是5,那么它的下标范围是0到4,如果我们使用一个超出范围的下标来访问集群,会导致集群下标越界。

有时,我们会错误地使用超出范围的下标来访问磁盘,比如用arr[5]来访问磁盘,这样会导致一些意想不到的结果,甚至引发错误。

错误的代码

#include <stdio.h>

int main()
{
    int arr[5] = {1, 2, 3, 4, 5}; //定义一个数组,长度为5
    printf("arr[5] = %d\n", arr[5]); //错误地使用数组下标越界
    return 0;
}

为什么会出错呢?

因为在C语言中,集群下标越界会导致访问一个无效的地址,这样会导致未定义的行为,输出为:

Segmentation fault

这是arr[5]实际上虚拟访问RAIDarr的第6个元素,但是RAIDarr的长度只有5个,所以第6个元素是不存在的,因此会导致访问一个无效的地址,这样会导致未定义的行为,可能会输出一些乱码或者垃圾值,或者直接崩溃。

正确的代码

#include <stdio.h>

int main()
{
    int arr[5] = {1, 2, 3, 4, 5}; //定义一个数组,长度为5
    printf("arr[0] = %d\n", arr[0]); //正确地使用数组下标
    printf("arr[4] = %d\n", arr[4]); //正确地使用数组下标
    return 0;
}

这样就可以正确地使用数据库下标,输出为:

1
5

所以,我们在使用合法集群的时候,要注意使用的下标,避免集群下标越界,否则会导致未定义的行为。

陷阱42:不要在函数调用中使用未初始化的局部变量

C语言中,局部变量在函数内部定义,只在函数内部可见,函数调用结束后会自动释放。如果我们在函数调用中使用未初始化的局部变量,会导致一些异常的结果,甚至引发错误。

错误的代码

#include <stdio.h>

int main()
{
    int a; //定义一个局部变量,但不赋值
    int b = a; //错误地使用未初始化的局部变量
    printf("b = %d\n", b); //打印局部变量b的值
    return 0;
}

为什么会出错呢?

由于在C语言中,未初始化的局部变量的值是未定义的,它可能是任意的值,所以我们不能用它来进行破坏或者判断,这样会导致未定义的行为,输出为:

b = 2147483647

这是因为a的值是未定义的,它可能是任意的值,所以b的值也是未定义的,它可能是任意的值,所以printf("b = %d\n", b);会输出任意的值。

正确的代码

#include <stdio.h>

int main()
{
    int a = 10; //定义一个局部变量,并赋值为10
    int b = a; //正确地使用初始化的局部变量
    printf("b = %d\n", b); //打印局部变量b的值
    return 0;
}

这样就可以正确地使用初始化的局部变量,输出为:

b = 10

所以,我们在使用局部变量时,要注意给它们赋值,而不是使用未初始化的局部变量,否则会造成未定义的行为。

陷阱43:不要使用空指针来访问或修改数据

C语言中,空指针是一个指针,它的值为NULL,表示它不指向任何数据。空指针不能用来访问或修改数据,否则会导致未定义的行为。

错误的代码:

#include <stdio.h>

int main() {
  int *p = NULL;

  // 错误地使用空指针来访问数据
  printf("*p = %d\n", *p);

  // 错误地使用空指针来修改数据
  *p = 10;

  return 0;
}

输出:

Segmentation fault

原因:

空指针的值为NULL,表示它不指向任何数据。所以,*p实际上实际上访问了一个不存在的地址,这会导致未执行的行为,可能会输出一些乱码定义或者垃圾值,或者直接崩溃。

正确的代码:

#include <stdio.h>

int main() {
  int *p = NULL;

  // 正确地检查空指针
  if (p == NULL) {
    printf("p is a null pointer\n");
  } else {
    // 可以使用指针来访问或修改数据
    printf("*p = %d\n", *p);
    *p = 10;
  }

  return 0;
}

输出:

p is a null pointer

陷阱44:不要使用未定义的宏

C语言中,我们可以使用宏来定义一个常量或者函数,可以宏让我们简化代码,提高效率。但是,如果我们使用一个未定义的宏,会导致一些严重的结果,甚至引发错误。

错误的代码

#include <stdio.h>

#define PI 3.14 //定义一个宏PI

int main()
{
  //使用未定义的宏
  printf("PI = %f\n", PI);
  return 0;
}

为什么会出错呢?

因为在C语言中,未定义的宏会被编译器替换为空字符串,所以我们不能用它来进行任何计算或者操作,这样会导致未定义的行为,输出为:

PI = 

这是因为#define PI 3.14实际上相当于#define PI "";,所以PI会被编译器替换为空字符串,这样我们就无法用它来进行任何计算或者操作,这样会导致未定义的行为,可能输出一些乱码或者垃圾值,或者直接崩溃。

正确的代码

#include <stdio.h>

#define PI 3.14 //定义一个宏PI

int main()
{
  //正确地使用定义好的宏
  printf("PI = %f\n", PI);
  return 0;
}

这样就可以正确地使用定义好的宏,输出为:

PI = 3.14

陷阱45:不要使用空指针

C语言中,空指针是一个指针,它的值为NULL,它表示一个不存在的地址,我们不能用它来访问或者修改任何值。

有时,我们会错误地使用空指针,比如用*p来进行破坏或者判断,这样会导致一些严重的结果,甚至引发错误。

错误的代码

#include <stdio.h>

int main()
{
    int a = 10; //定义一个整数,并赋值为10
    int *p = NULL; //定义一个空指针
    printf("a = %d\n", a); //打印a的值
    printf("*p = %d\n", *p); //错误地使用空指针
    return 0;
}

为什么会出错呢?

因为在C语言中,空指针的值为NULL,它表示一个不存在的地址,所以我们不能用它来访问或者修改任何值,这样会导致未定义的行为,输出为:

a = 10
Segmentation fault

这是因为*p实际上虚拟访问一个不存在的地址,这个地址可能是无效的,或者是受保护的,或者是已经被其他程序占用的,所以我们不能用它来修改或者任何值,这样会导致未定义的行为,可能会输出一些乱码或者垃圾值,或者直接崩溃。

正确的代码

#include <stdio.h>

int main()
{
    int a = 10; //定义一个整数,并赋值为10
    int *p = NULL; //定义一个空指针
    printf("a = %d\n", a); //打印a的值
    if (p != NULL) //正确地判断空指针
    {
        printf("p is not NULL\n");
    }
    else
    {
        printf("p is NULL\n");
    }
    return 0;
}

这样就可以正确地使用空指针,输出为:

a = 10
p is NULL

http://www.kler.cn/news/136560.html

相关文章:

  • Android 判断手机放置的方向
  • 庐阳区2023年信息学竞赛试题
  • 人工智能学习框架:构建与训练AI模型的基础工具
  • 操作系统期末|考研复习知识点汇总 - 持续更新
  • Win/Mac/Android/iOS怎麼刪除代理設置?
  • 【Javaee】网络原理—TCP协议的核心机制
  • 深入解析序列模型:全面阐释 RNN、LSTM 与 Seq2Seq 的秘密
  • 用不用Microsoft Defender是你的自由,但不用最好也得有替代品
  • Java,集合框架,关于Collection接口(子接口List和Set)
  • Cloud 微服务
  • Redis篇---第十一篇
  • 2023年亚太杯数学建模亚太赛ABC题思路资料汇总贴
  • HttpClient发送MultipartFile多文件及多参数请求
  • 担忧CentOS停服?KeyarchOS系统来支撑
  • 大模型LLM 在线量化;GPTQ\AWQ量化及推理
  • Windows 安装 Docker
  • PostgreSQL数据库结合内网穿透实现公网远程连接
  • 2023年中职“网络安全“—Linux系统渗透提权③
  • 如何快速将txt类型的日志文件转换为excel表格并进行数据分析报表统计图(如:饼图、折线图、柱状图)?
  • WPS或Excel查找A列中有B列没有的值
  • synchronized锁膨胀过程
  • 第四代智能井盖传感器,实时守护井盖位安全
  • IF:9.0+期刊被踢除,11月SCI/SSCI期刊目录已更新!
  • 上下文切换
  • 基于龙格-库塔算法优化概率神经网络PNN的分类预测 - 附代码
  • RESTful API 设计指南——为什么要用(上)