热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在C++中使用变量而不是`#define`指定数组大小是不好的做法吗?(C错误:在文件范围内进行了可变修改)

如何解决《在C++中使用变量而不是`#define`指定数组大小是不好的做法吗?(C错误:在文件范围内进行了可变修改)》经验,为你挑选了1个好方法。

在C中,const不允许使用变量声明数组大小,即使它是变量.例如:这无法在C中编译:

#include 

const int SIZE = 2;
int a[SIZE];

int main()
{
    a[0] = 1;
    a[1] = 2;
    printf("%i, %i", a[0], a[1]);       
    return 0;
}

在C中运行此代码

输出:

$gcc -o main *.c
main.c:5:5: error: variably modified ‘a’ at file scope
 int a[SIZE];
     ^

但是,在C++中,它运行得很好.
在C++中运行上面的代码.

输出:

$g++ -o main *.cpp
$main
1, 2

要使其在C中运行,必须使用#define而不是变量.即:

这在C或C++中运行得很好:

#include 

#define SIZE 2
// const int SIZE = 2;
int a[SIZE];

int main()
{
    a[0] = 1;
    a[1] = 2;
    printf("%i, %i", a[0], a[1]);
    return 0;
}

在C中运行此代码

因此,在C++中,我几乎总是使用变量而不是#define声明我的数组大小.我只是使数组大小变量const,这一切都很好!最近我开始在纯C中进行大量的单片机编程,然而,当我遇到这个错误并找出问题时,一位高级开发人员告诉我使用除#define-ed常量之外的任何东西都是不好的做法(或者可能是硬编码的数字) )声明数组大小.

这是真的?在C++中使用const变量而不是#define在指定数组大小时是不好的做法?如果是这样,为什么?

在C中,显然你坚持#define:你别无选择.但是在C++中你显然至少有两个选择,那么一个比另一个好吗?使用一个比另一个有风险吗?

有关:

    C中文件范围的可变修改数组

    static const vs #define <- 这是一个可靠的问题,非常有帮助.这绝对与我的问题有关,但我的问题并不重复,因为虽然它们都是关于const vs #define,但我的问题是一个非常特殊的情况,其中一个选项甚至不能用一种定期的语言工作被认为是C++的一个子集.这是非常不寻常的,并使我的问题成为一个更窄的子集,符合这个其他问题的广泛范围.因此,不重复.

    https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es31-dont-use-macros-for-constants-or-functions

    "static const"vs"#define"vs"enum"

    https://en.wikipedia.org/wiki/Variable-length_array#C99

P.W.. 6

在这件事上遵循Scott Meyer的建议会很好.从他的书"Effective C++":
第2项:首选consts,enums和inline到#defines.

适用于您的示例的项目摘要.

这个项可能更好地被称为"更喜欢编译器到预处理器",因为它#define可能被视为它本身不是语言的一部分.这是其中一个问题.

当你做这样的事情时,

#define SIZE 2

SIZE 编辑器可能永远不会看到符号名称; 在源代码到达编译器之前,它可能被预处理器删除.因此,名称SIZE可能无法输入到符号表中.如果在编译过程中出现涉及使用常量的错误,这可能会造成混淆,因为错误消息可能2不是指代SIZE.如果SIZE在头文件中定义了你没有写,你就不知道它2来自哪里 ,而你却浪费时间跟踪它.此问题也可能出现在符号调试器中,因为您编程的名称可能不在符号表中.解决方案是用常量替换宏:
const double SIZE = 2; // uppercase names are usually for macros, hence the name change
作为语言常量,SIZE编译器肯定会看到它,并且肯定会输入到它们的符号表中.

✦对于简单常量,首选const对象或枚举到#defines.
✦对于类似函数的宏,首选内联函数为#defines.

另请参阅"第3项:尽可能使用const".有关其用法和使用例外的更多信息.

所以在标题中回答你的问题:
,使用变量而不是#defineC++ 指定数组大小并不是一个坏习惯.



1> P.W..:

在这件事上遵循Scott Meyer的建议会很好.从他的书"Effective C++":
第2项:首选consts,enums和inline到#defines.

适用于您的示例的项目摘要.

这个项可能更好地被称为"更喜欢编译器到预处理器",因为它#define可能被视为它本身不是语言的一部分.这是其中一个问题.

当你做这样的事情时,

#define SIZE 2

SIZE 编辑器可能永远不会看到符号名称; 在源代码到达编译器之前,它可能被预处理器删除.因此,名称SIZE可能无法输入到符号表中.如果在编译过程中出现涉及使用常量的错误,这可能会造成混淆,因为错误消息可能2不是指代SIZE.如果SIZE在头文件中定义了你没有写,你就不知道它2来自哪里 ,而你却浪费时间跟踪它.此问题也可能出现在符号调试器中,因为您编程的名称可能不在符号表中.解决方案是用常量替换宏:
const double SIZE = 2; // uppercase names are usually for macros, hence the name change
作为语言常量,SIZE编译器肯定会看到它,并且肯定会输入到它们的符号表中.

✦对于简单常量,首选const对象或枚举到#defines.
✦对于类似函数的宏,首选内联函数为#defines.

另请参阅"第3项:尽可能使用const".有关其用法和使用例外的更多信息.

所以在标题中回答你的问题:
,使用变量而不是#defineC++ 指定数组大小并不是一个坏习惯.


所以回答标题中的Q:不,恰恰相反.
推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 去掉空格的方法——Python工程师招聘标准与实践
    本文介绍了去掉空格的方法,并结合2019独角兽企业招聘Python工程师的标准与实践进行讨论。同时提供了一个转载链接,链接内容为更多相关信息。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 热血合击脚本辅助工具及随机数生成器源码分享
    本文分享了一个热血合击脚本辅助工具及随机数生成器源码。游戏脚本能够实现类似真实玩家的操作,但信息量有限且操作不可控。热血合击脚本辅助工具可以帮助玩家自动刷图、换图拉怪等操作,并提供了雷电云手机的扩展服务。此外,还介绍了使用mt_rand函数作为随机数生成器的代码示例。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 本文主要介绍了gym102222KVertex Covers(高维前缀和,meet in the middle)相关的知识,包括题意、思路和解题代码。题目给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,要求所有点覆盖的权值之和膜qn小于等于36。文章详细介绍了解题思路,通过将图分成两个点数接近的点集L和R,并分别枚举子集S和T,判断S和T能否覆盖所有内部的边。文章还提到了使用位运算加速判断覆盖和推导T'的方法。最后给出了解题的代码。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
    原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ... [详细]
  • MySQL5.6.40在CentOS764下安装过程 ... [详细]
  • VS用c语言连接mysql,c语言连接mysql完整演示
    #include#includeintmain(){MYSQL*conn;创建一个指向mysql数据类型的指针connmysql_init(NULL);mysql的初始化if(!c ... [详细]
author-avatar
Rocky柱子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有