Questions tagged «c»

C是用于操作系统,游戏和其他高性能工作的通用计算机编程语言。

10
难道“总是初始化变量”会导致重要的错误被隐藏吗?
C ++核心准则具有ES.20规则:始终初始化一个object。 避免使用预先设置的错误及其相关的未定义行为。避免理解复杂的初始化问题。简化重构。 但是,此规则无助于发现错误,只会将它们隐藏起来。 假设程序具有执行路径,在该路径中使用未初始化的变量。这是一个错误。除了不确定的行为外,这还意味着出现了问题,程序可能无法满足其产品要求。当将其部署到生产中时,可能会造成金钱损失,甚至更糟。 我们如何筛选错误?我们编写测试。但是测试不能覆盖100%的执行路径,测试也不能覆盖100%的程序输入。不仅如此,即使测试覆盖了错误的执行路径-它仍然可以通过。毕竟,这是未定义的行为,一个未初始化的变量可以具有一个有效值。 但是除了测试外,我们还有一些编译器,它们可以将0xCDCDCDCD写入未初始化的变量。这会稍微提高测试的检测率。 更好的是-有诸如Address Sanitizer之类的工具,它将捕获所有未初始化内存字节的读取。 最后是静态分析器,它可以查看程序并告诉您该执行路径上有一个先读后设置的内容。 因此,我们有许多功能强大的工具,但是如果我们初始化变量清理器,将一无所获。 int bytes_read = 0; my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*); // bytes_read is not changed on read error. // It's a bug of "my_read", but detection is suppressed by initialization. buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here. // …
35 c++  c 

8
为什么Clang / LLVM在覆盖所有枚举情况的switch语句中警告我使用default?
考虑以下枚举和switch语句: typedef enum { MaskValueUno, MaskValueDos } testingMask; void myFunction(testingMask theMask) { switch (theMask) { case MaskValueUno: {}// deal with it case MaskValueDos: {}// deal with it default: {} //deal with an unexpected or uninitialized value } }; 我是一个Objective-C程序员,但是我已经用纯C语言编写了此文档,以供更广泛的读者使用。 带有-Weverything的Clang / LLVM 4.1在默认行警告我: 开关中的默认标签,涵盖所有枚举值 现在,我可以看到为什么会出现这种情况:在理想情况下,参数中唯一输入的值theMask将在枚举中,因此不需要默认值。但是,如果出现一些hack并将未初始化的int放入我的漂亮函数中怎么办?我的功能将作为库中的一部分提供,我无法控制其中的内容。使用default是处理此问题的一种非常简洁的方法。 为什么LLVM众神认为这种行为不符合他们的地狱装置?我应该在前面加上if语句来检查参数吗?


5
我应该通过参数还是通过返回值初始化C结构?[关闭]
我工作的公司正在通过初始化函数来初始化所有数据结构,如下所示: //the structure typedef struct{ int a,b,c; } Foo; //the initialize function InitializeFoo(Foo* const foo){ foo->a = x; //derived here based on other data foo->b = y; //derived here based on other data foo->c = z; //derived here based on other data } //initializing the structure Foo foo; InitializeFoo(&foo); 我遇到了一些尝试初始化我的结构的问题: …

8
如果C允许,为什么Java完全不允许数字条件,如if(5){…}?
我有两个小程序: C #include <stdio.h> int main() { if (5) { printf("true\n"); } else { printf("false\n"); } return 0; } 爪哇 class type_system { public static void main(String args[]) { if (5) { System.out.println("true"); } else { System.out.println("false"); } } } 报告错误消息: type_system.java:4: error: incompatible types: int cannot be converted to …
33 java  c  type-systems 

7
用C语言编写性能?[关闭]
我知道我经常听到C通常比C ++具有性能优势。在我意识到MSVC似乎甚至不支持C的最新标准之前,我并没有真正想到它,但据我所知,最新的版本支持C99。 我打算编写一个包含一些代码的库以在OpenGL中呈现,以便我可以重用它。我打算用C语言编写该库,因为在图形方面,任何性能的提高都是值得欢迎的。 但这真的值得吗?使用该库的代码很可能是用C ++编写的,而我通常更喜欢用C ++编写代码。 但是,如果产生的性能差异很小,我可能会选择C。 可能还需要注意的是,这个库将是我可以在Windows / OS X / Linux上使用的库,并且我很可能会原生编译所有内容(Windows的MSVC,OS X的Clang或GCC以及Linux的GCC。 。或可能是英特尔的所有编译器)。 我环顾四周,并找到了一些基准测试等,但是我所看到的所有内容都是针对GCC而不是MSVC和Clang的。此外,基准测试未提及所用语言的标准。有人对此有任何想法吗? 编辑:经过几年的经验,我只是想分享我对这个问题的观点。我最终用C ++编写了一个问这个问题的项目。我大约在同一时间在C中启动了另一个项目,因为我们希望获得尽可能少的性能,并且需要该项目在C中可链接。几个月前,我到达了真正需要地图和高级界面的地步字符串操作。我知道C ++标准库中的这种功能,并最终得出结论:标准库中的那些结构可能会比在合理的时间内可以在C中实现的映射和字符串更好并且更稳定。通过向C ++代码编写C接口,可以很容易地满足在C中可链接的要求,该接口可以通过不透明类型快速完成。用C ++重写库似乎比用C编写库快得多,而且不容易出现错误,尤其是内存泄漏。我还能够使用标准库线程库,该库比使用特定于平台的实现要容易得多。最后,我相信用C ++编写库可以带来巨大的好处,而性能成本可能很小。我尚未对C ++版本进行基准测试,但是我认为使用标准库数据结构可能会获得比我编写的性能更高的性能。我相信用C ++编写库可以带来巨大的好处,而性能成本可能很小。我尚未对C ++版本进行基准测试,但是我认为使用标准库数据结构可能会获得比我编写的性能更高的性能。我相信用C ++编写库可以带来巨大的好处,而性能成本可能很小。我尚未对C ++版本进行基准测试,但是我认为使用标准库数据结构可能会获得比我编写的性能更高的性能。

11
typedefs和#defines
我们每个人肯定都使用了typedefs和#defines。今天,在与他们一起工作时,我开始思考一件事。 请考虑以下两种情况,以使用int其他名称的数据类型: typedef int MYINTEGER 和 #define MYINTEGER int 与上述情况类似,在很多情况下,我们可以使用#define很好地完成某件事,并且也可以使用typedef进行相同的操作,尽管我们进行相同操作的方式可能完全不同。#define还可以执行typedef不能执行的MACRO操作。 尽管使用它们的基本原因是不同的,但是它们的工作有何不同?当两者都可以使用时,什么时候应该优先使用另一种呢?另外,在某些情况下,是否可以保证一个比另一个更快?(例如,#define是预处理程序指令,因此所有操作都比编译或运行时更早完成)。

13
低级编程-对我有什么用?[关闭]
多年以来,我一直在考虑深入研究“低级”语言。对我来说,这意味着C语言和汇编语言。但是,我还没有时间这样做,也从来没有必要。 现在,因为我看不到任何必要,所以我觉得我应该只是安排某个时间点来学习该主题,或者永远放弃该计划。 我的位置 在过去的四年中,我一直专注于可能会发生变化的“ Web技术”,而我是一名应用程序开发人员,这不太可能发生变化。 在应用程序开发中,我认为可用性是最重要的。您编写的应用程序将被用户“消耗”。这些应用程序越有用,您产生的价值就越大。 为了获得良好的可用性,我相信以下是可行的 良好的设计:经过深思熟虑的功能可通过深思熟虑的用户界面访问。 正确性:如果实施不正确,那么最好的设计一文不值。 灵活性:应用程序A应该不断发展,以便其用户不必切换到具有A可以实现的具有新功能的其他应用程序B。解决同一问题的应用程序的功能不应有所不同,而应在原理上有所不同。 性能:性能有助于获得良好的用户体验。理想情况下,应用程序始终具有响应能力,并且可以相当快地执行其任务(基于其频率)。性能优化的价值超出了用户可察觉的范围,这值得怀疑。 我认为除了性能之外,低级编程不会对我有所帮助。但是,出于性能考虑,以低级语言编写整个应用程序对我来说还为时过早。 我的问题 低级编程可以教给我什么,其他语言不能教给我什么?我是否缺少某些东西,或者仅仅是一项技能,而这对于应用程序开发几乎没有用?请理解,我不是在质疑C和汇编的价值。只是,在我的日常生活中,我非常高兴地了解到这个世界的所有错综复杂的东西并为我进行了管理(主要是通过用C / C ++编写的层以及自己进行汇编)。我只是看不到任何新概念,对我而言只是细节。那对我有什么用呢? 我的结论 感谢大家的回答。我必须说,没有人真的让我感到惊讶,但是至少现在我可以肯定,我会放弃对此感兴趣的领域,直到需要它为止。 据我了解,如今为当今的CPU中使用的处理器编写程序集不仅不必要地复杂,而且有可能导致运行时性能比C语言差。由于OOE的原因,手工优化几乎是不可能的,尽管您没有获得编译器可以自动进行的各种优化。而且,该代码是可移植的,因为它使用了一小部分可用命令,或者经过了优化,但可能仅在一种体系结构上工作。 编写C不再像以前那样需要。如果要用C编写应用程序,我将尽可能使用经过测试和建立的库和框架,这将使我免于实现字符串复制例程,排序算法和其他在大学中用作练习的东西。我自己的代码将以类型安全为代价更快地执行。我既不希望在常规应用程序开发过程中重新发明轮子,也不希望通过查看核心转储来进行调试:D 我目前正在尝试语言和解释器,所以我想发布什么内容,我想尽管C ++也可以做到这一点,但可以将一个可行的概念移植到C上。 再次感谢大家的回答和见解。

8
直接使用Make做过时了吗?[关闭]
因此,我遇到了很多有关直接创建makefile的评论/帖子/等等,以及在2015年如何做是一件愚蠢的事情。我知道诸如CMake之类的工具,实际上我经常使用CMake。事实是,CMake只是为您创建Makefile,并帮助消除了您自己做的乏味。当然,它还添加了许多其他强大的功能……但是最后它仍然是一个Makefile。 所以我的问题是,关于make的“过时”讨论是指整个Make实用程序,还是仅仅是手动编写自己的Makefile的想法?我根本不使用IDE进行C / C ++开发(只是emacs),所以我总是写Makefile。 如果Make被认为已经过时,那么C / C ++开发人员应该使用什么来构建小型个人项目?
31 c++  c  builds  make  cmake 

2
C预处理程序的起源是什么?
C预处理程序已附加到C,但是它的语法与主要语言完全不同: 语法上显着的空格(行尾终止一条语句,宏确定替换列表的开始后的间隔) 基于关键字的块而不是支撑块,elif而不是else if 关键字主导的定义,而不是声明反射的使用,=对于值定义,否 其他字符串语法的提示(#include <>vs #include "") 惰性求值(显然是C的;但是6.10.3.1可以理解为也暗示着宏扩展的特定顺序,在一些重要的地方) 真的看起来根本不像C!从技术上讲,它是它自己的语言,但是它一直被用作C的几乎不可或缺的部分,并且它在语法上不与它集成似乎很奇怪。 维基百科没有谈论它的历史。波特兰模式存储库给了它一个提及,但没有详细介绍它是由其他人(而不是C的其他人)设计的。具有C历史的Dennis Ritchie的网站可能有答案,但不幸的是没有不再可用。 宏引擎,它显然已经从运行系统语言,这可以解释非常不同的语义一些差异,但不是视觉设计方面(这也不清楚现代眼光是否本来是打算作为能够在中样的的乐趣,其替代系统是否允许,或者它是否仅仅是在功能强大的优化程序之前的一种内联函数的便捷方式)。如果实际上像C一样的语义已经成为起点,那感觉似乎更接近最终成为C ++模板的东西向宏的逻辑发展。但是,没有比语法更具体的证据了。 我们是否有任何记录说明为何采用这种方式设计,或者创作者的影响是什么?
30 c  history  macros 

5
如果数字太大,会溢出到下一个存储位置吗?
我一直在审查C编程,但有几件事困扰着我。 让我们以以下代码为例: int myArray[5] = {1, 2, 2147483648, 4, 5}; int* ptr = myArray; int i; for(i=0; i<5; i++, ptr++) printf("\n Element %d holds %d at address %p", i, myArray[i], ptr); 我知道一个int可以容纳正数2,147,483,647的最大值。因此,通过遍历它,是否“溢出”到下一个内存地址,从而导致元素2在该地址处显示为“ -2147483648”?但这并没有真正的意义,因为在输出中它仍然说下一个地址保持值为4,然后是5。如果该数字已溢出到下一个地址,则不会改变存储在该地址的值? 我隐约记得在MIPS Assembly中进行编程时,看着地址在程序执行过程中逐步改变了值,分配给这些地址的值会改变。 除非我没有记错,否则这是另一个问题:如果分配给特定地址的数字大于类型(如myArray [2]中的类型),那么它是否不影响存储在后续地址中的值? 示例:我们在地址0x10010000处有int myNum = 40亿。当然,myNum不能存储40亿,因此它在该地址显示为负数。尽管不能存储这么大的数字,但它对存储在后续地址0x10010004上的值没有影响。正确? 内存地址仅具有足够的空间来容纳某些大小的数字/字符,如果大小超出限制,则其表示方式将有所不同(例如尝试将40亿存储到int中,但它将显示为负数),并且因此,它不会影响下一个地址中存储的数字/字符。 对不起,如果我过分。从那以后,我整天都在闹大闹鬼。

10
指针在C语言中保存的数据的“类型”是什么?
我知道指针保存地址。我知道,指针的类型基于它们指向的数据的“类型”而被“一般地”知道。但是,指针仍然是变量,它们所持有的地址必须具有数据“类型”。根据我的信息,地址为十六进制格式。但是,我仍然不知道该十六进制是什么“数据”类型。(请注意,我知道十六进制是什么,但是10CBA20例如,当您说这是一个字符串吗?整数吗?是什么?当我想访问该地址并对其进行操作..本身时,我需要知道其类型。这这就是为什么我问。)
30 c  pointers 


2
为什么C字符串文字是只读的?
字符串文字为只读的优点是(-ies / -ied): 另一种射击自己的方式 char *foo = "bar"; foo[0] = 'd'; /* SEGFAULT */ 无法优雅地初始化一行中的可读写单词数组: char *foo[] = { "bar", "baz", "running out of traditional placeholder names" }; foo[1][2] = 'n'; /* SEGFAULT */ 使语言本身复杂化。 char *foo = "bar"; char var[] = "baz"; some_func(foo); /* VERY DANGEROUS! */ some_func(var); /* …
29 c  memory  strings 

10
使用指针变量不是内存开销吗?
在C和C ++之类的语言中,使用指向变量的指针时,我们还需要一个内存位置来存储该地址。那这不是内存开销吗?如何补偿?时间紧迫的低内存应用程序中使用指针吗?
29 c++  c  pointers 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.