C 语言家族的笔记
文章平均质量分 75
C 语言家族相关内容的笔记、问题及其解决方案。C 语言家族除了 ANSI C,还包括 C++、Objective-C、ISPC、NVCC 等等 C 语言的变体。
zhonguncle
居高才能临下,深入才能浅出(这话是谁说的呢?肯定不是鲁迅)
展开
-
C++中的enum(枚举)是什么,以及与C中enum的不同之处
最近在看《A Tour of C++ 3rd》的时候发现 C 和 C++ 的 enum虽然使用起来比较相似,但是目的却略有不同。关于枚举的概念还请见之前写过一篇关于 C 的那篇博客《C语言中enum(枚举)详解》,这里不再赘述。本文侧重 C++ 与 C 不同的地方。首先,默认情况下与 C 一样,值的类型为整数,所以下面样式的代码依旧可以使用:原创 2024-06-16 11:37:28 · 441 阅读 · 0 评论 -
如何使用rdtsc和C/C++来测量运行时间(如何使用内联汇编和获取CPU的TSC时钟频率)
CPUID 签名就是当EAX=1时,cpuid在EAX中的返回值。内容如下:实际上并不会用到整个EAX的内容,只要取得处理器的Model部分即可。原创 2024-04-22 19:33:11 · 1669 阅读 · 1 评论 -
如何使用Clang和opt、dot(LLVM配套工具)生成CFG、调用图、依赖等多种图(提示错误The `opt -passname` syntax for the new pass manager)
偶然看到有人用 LLVM 配套工具生成的 CFG 图,就想看看怎么做出来的。但是吧,LLVM 就在最近一年左右的时间内修改了生成方法,导致网络上国内外很多人记录的方法无法使用,所以写本文记录一下。假设这里有一个源代码文件,内容是计算矩阵(代码就不贴了,你随便找个程序就行)。首先需要使用和选项生成所需的 LLVM IR 文件,需要注意的是,不同优化等级生成的图像是不一样的,所以要注意是否使用等选项(最后会放出对比)。这里推荐使用选项使得编译流程停止在汇编器之前,因为并不需要走完整个编译流程。这时候会产生一个原创 2024-02-04 13:36:18 · 1263 阅读 · 0 评论 -
如何通过ISPC使用Xe(核显)进行计算
我一直以为 ISPC 的 Xe 是只包含独立显卡的,比如 A770 这些,没想到看了眼文档是可以使用核显的,但只能在 Linux 和 Windows 上,macOS 不行,就想试试看。写本文是因为 ISPC 已经出现了三四个版本的大改,但是官方文档并未提及这些。不过这篇官方文档依旧可以带来很多帮助。原创 2024-01-16 00:02:52 · 1034 阅读 · 0 评论 -
如何在C/C++中测量一个函数或者功能的运行时间(串行和并行,以及三种方法的实际情况对比)
本文算是一个比较完整的关于在 C/C++ 中测量一个函数或者功能的总结,最后会演示三种方法的对比。最常用的clock()最常用的测量方法是使用clock()来记录两个 CPU 时间点clock_t,然后做差。这个方法的好处在于非常简单易写,timespec。clock_gettime()的参数CLOCK_REALTIME表示系统层面的实时时间;这个地方还可以用CLOCK_MONOTONIC,这个值是从系统启动开始一直运行的,一直连续的不跳跃的(除非手动改了),这个要比CLOCK_REA:原创 2023-11-27 23:54:22 · 6878 阅读 · 4 评论 -
C语言获取命令行选项(option/flag)和输入的内容(argv)的一种巧妙的办法
这个方法很难说比之前那个方法好还是不好,但是在处理一种情况的时候可能会好一些,就是当你必须要有一个参数,但这个参数并没有选项的时候。中写到 Unix 命令行选项的惯例是在选项前面加上一个。举个例子,比如说用户必须输入一个地址,当然你可以使用。如果输入地址不正确,再进行错误处理。如果你看过我之前的那篇博客。,用来区分选项名和参数。,但是也可以直接用最后的。希望能帮到有需要的人~原文中提到的方法是用。原创 2023-11-23 12:19:28 · 766 阅读 · 0 评论 -
如何使用C/C++刷新修改已经打印显示在终端上的内容
写本文的起源是因为在安装一些工具的时候,发现在终端上并行安装的情况下,显示安装信息是会修改之前已经打印出来的内容,这是怎么做到的呢?抱着对这个问题的好奇我进行了一些探索。原创 2023-10-14 08:02:54 · 2339 阅读 · 1 评论 -
如何解决使用 ISPC 构建编译项目代码的时候出现_ISPCAlloc、_ISPCLaunch、_ISPCSync的连接器错误
一般在编译 ISPC 代码到时候,构建方法如下:但是在一些情况下连接器会报以下错误:出现这个问题是因为你使用了 ISPC 中的,这就需要使用 ISPC 任务系统(ISPC tasking system)。但是这个系统默认是不包含的,代码在一个名为的文件中,你可以在https://github.com/ispc/ispc/tree/main/examples/common找到这个文件,也可以复制以下代码到你自己创建的文件中:接下来假设这个文件在你的项目目录中,如下(当然你也可以放到一个固定位置,这样每个原创 2023-09-05 13:48:29 · 198 阅读 · 0 评论 -
使用gcc展示完整的编译过程(gcc预处理模式、编译模式、汇编模式、连接模式)
最近在了解 clang/llvm 的时候突然发现一件事:gcc是一个工具集合,包含了或者调用将程序源代码转换成可执行程序文件的所有工具,而不只是简单的编译器。这帮助我对“编译器”有了更深刻的理解,所以写下本文作为记录。从源代码转换成可执行程序的完整过程,也就是我们平时所说的“编译过程”,实际如下(圆角矩形表示代码,矩形表示各种处理器)可以看到从源代码到可执行程序要经过预处理器(preprocessor)、编译器(compiler)、汇编器(assembler)和连接器(linker)或加载器(loader)原创 2023-06-08 11:33:57 · 5120 阅读 · 3 评论 -
使用 C++ 验证中心极限定理(通过生成一个PPM格式的图像验证非均匀概率的离散事件在样本数量足够大时,符合正态分布曲线)
我想写本文的原因是看到著名数学科普账号 3Blue1Brown 发布的发布的【官方双语】什么是中心极限定理?中提到:不论这个离散型事件的各种情况概率是不是平均的,当数量一定大时,还是会符合正态分布曲线。我就想自己试试看是不是这种情况,因为我觉得中心极限定理和正态分布是一个概率论中很神奇的一部分。本文使用骰子点数当作离散型事件,求点数之和的概率。先实现均匀分布的状态下的程序,再调整为不均匀分布的概率,完整源代码放在最后,防止因为头文件等问题导致错误。原创 2023-05-16 18:42:15 · 624 阅读 · 0 评论 -
C——Union是什么?Union和Struct这么像,区别在哪?为什么还要创造出union呢?需要在哪里使用呢?
在 C 语言中,有一种叫做union的变量,是用来在不同的情况下,存放不同类型和大小的对象的变量。这与结构体struct很相似:结构体是一个或多个变量的集合。union 的声明方式非常简单,也与struct一模一样二者这么像,那么二者的区别在哪里呢?或者说,为什么要弄两个这么像的东西呢?C 又不是 C++,一些功能是由不同的小组开发的,一些功能上会重叠。首先是表面的不同,struct和union在使用目的上完全不一样,union并不像struct会同时存放大括号中列出的每个变量,如果你尝试下面的代码原创 2023-05-11 08:04:03 · 569 阅读 · 0 评论 -
使用 nvcc 的时候出现“helper_cuda.h”: No such file or directory错误该怎么办(其他xxx.h也是同样的解决方法)
今天在命令行中使用nvcc的时候,出现了“helper_cuda.h”: No such file or directory错误。这个错误信息表示:在编译的时候,找不到helper_cuda.h头文件(其他xxx.h如果也找不到,那么下面的解释和解决方法也通用)。出现这个问题的原因是,大多数编译器寻找头文件的方法就一种:在环境变量中设置的目录下去找这个头文件。如果环境变量中存放的目录下没有这个头文件,就找不到了。甚至就没有创建或设置好这个环境变量,那更不可能找到了。不论使用何种编译器,这种问题都是常见问原创 2023-05-02 11:41:42 · 3065 阅读 · 0 评论 -
C——Typedef是什么?如何使用?有何便利之处?
typedef是 C 语言中的一个特色功能,被用于创建新的类型名称,从名称“type def(ine)”也可以看出其功能。typedef类似于 Unix 中的alias程序的功能,为一个对象添加另外一个名称,typedef使得多个名称其实对应的是同一个程序,但是typedef操作的对象是数据类型,也就是给数据类型“起外号”,这个外号一般首字母大写,用于表示不是基础数据类型。在 C 语言中,typedef与宏#define很相似,二者的区别放到最后,因为需要先理解typedef,才能理解其与宏的区别。原创 2023-04-26 22:57:57 · 1043 阅读 · 0 评论 -
C语言中enum(枚举)详解
enum是 enumerate(列举,枚举)一词的缩写,是 C 语言中的一种常量,被称为 enumeration constant。enum提供了一种很方便的方法来将值和名称关联起来,是#define的一种替代方法。enum可以看作是一种特殊的数组,是常量组成的列表,而且这个常量只能是整数型。所以如果是寥寥几个不相关、不连续的常量,直接定义几个常量就可以。但是如果是相关的或者连续的,使用enum效率更高。但是枚举与数组、元组不同的有 3点:看到这里你可能会想,必须要弄一个mon来获取值嘛?因为通过变原创 2023-04-19 16:20:27 · 14091 阅读 · 1 评论 -
C/C++ 如何实现和使用链表(linked list)
由于实现链表(Linked List)是实现一种数据结构,使用结构体(structure),而不是必须使用 Class。所以 C 和 C++ 没区别。原创 2022-08-17 21:58:38 · 1063 阅读 · 0 评论 -
C++ 笔记
本文基于 C++ 11,适合有 C 语言基础的阅读,只讲与C语言不同的地方。如果需要了解最新式语法,那么可以去看微软 Visual Studio 2022 的文档《C++标准库参考(STL)》原创 2022-09-02 15:32:02 · 970 阅读 · 0 评论 -
C++ 中的类(class)和对象(object)详解
类是具有相同的属性和操作的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性(数据变量)和操作(成员函数)两个主要部分。简而言之,类可以理解成是一种用户自己构造的数据类型,用这种数据类型声明的变量被称为 “对象”。类和结构体的区别那么类(class)和结构体(structure)有什么区别呢?结构体(structure)是一个包含了一个或者多个变量的集合,而且这些变量还可能是不同类型。结构体将其聚集,放在一个名称下面,这样方便使用。析构函数 构造函数原创 2022-08-19 14:23:56 · 6456 阅读 · 0 评论 -
C/C++ 多维数组探究
C 和 C++ 中都支持一维数组和多维数组。指针和数组的套用这里不讨论。实际开发中,指针数组比多维数组使用的多。多维数组必须在声明的时候初始化(也就是定义)。方式如下:原创 2022-08-15 21:11:17 · 354 阅读 · 0 评论 -
C/C++ 指针详解记录
类型 *指针名称;即可。比如来声明一个变量名为a,类型为intint * a;也就是比平时声明变量多了一个型号*。但是这里需要注意的是,声明时候的*a表示的是指针a包含的内存地址指向的内容,而a包含的则是地址。这个地址开始的一部分连续的空间将会划分给指针,以供存储地址,划出的大小由类型int决定,一般int为 2 个字节(这里的一个字节在有些英文文档中被称为“cell”)。...........................原创 2022-08-02 20:48:37 · 180 阅读 · 0 评论 -
C语言中函数main的参数argc和argv是什么
我的意思“程序运行时,会自动将从输入的获取的字符串分割成多个字符串,然后将这些字符串存放在 argv 数组,数组中最后一个元素被存放为空指针。但是一般情况下,如果单独说“argv”,指的是数组的指针。是一个存放字符类型元素地址的数组,因为 C 中是有字符串的概念的:将每个字符存放在 char 数组,最后一个元素为。是一个指向一个字符串数组的指针,数组包含了参数,每个字符串就是一个参数,最后一个元素为。这里需要细致说一下,之前写的太简洁了,评论有人没看懂,有一些底层逻辑需要说明一下。原创 2022-06-17 17:24:25 · 8719 阅读 · 6 评论 -
C——转义字符和ASCII码转换
这时候运行会发现显示就是“\t”。`134`是八进制的“\”的ASCII码。为什么这样就可以显示了呢?因为转义字符`\t`是一个字符,只占一位,但是在文本显示“\t”其实是显示两个字符——“\”和“t”。不过由于输入的时候把二者放在一起会自动识别成转义字符,所以将其中一个字符变成ASCII码即可。所以使用“\”加数字即可将ASCII数字变成对应的字符。不过需要注意的是,数字智能使用八进制和十六进制,十进制的不可用。而且十六进制数字之前需要加“x”,并且不能立马接下一个字符。原创 2021-07-09 17:42:44 · 1301 阅读 · 0 评论 -
C——对变量的二进制数进行操作
C语言中可以直接对值对应的二进制进行操作。这里会用到三个符号:~:对二进制进行取反。例如~0取反表示将0表示的·0000 0000(这里假设是8位的char)取反成1111 1111。这里有需要注意的点,介绍完下面两个符号之后再说。>>:将二进制右移,空位用0补上。例如2 >> 1表示将2表示的0000 0010右移移位,变成0000 0001,也就是1。<<:将二进制左移,使用方法同上。这两种移动方式如果移动0位的话,就等于没有任何操作发生,例如介绍完之后,说原创 2021-07-26 02:23:02 · 661 阅读 · 0 评论 -
C——char(字符串)转int
有时候需要对输入的数字进行计算之类的操作,这时候需要将char转int类型。char是一个单独字节,可以保存一个本地字符集的内容的类型。一般使用char[]的格式来使用。int就是一个范围较小的无符号整数类型。注意!这里指的方法是使用ASCII字符集:要将char转int需要一个小技巧,就是0-9在ASCII字符集中是按照顺序排列的,那么我们只需要一行简单的代码:b = a[0] - '0'将当前获取的char类型的a[0]表示的ASCII编号,减去'0'表示的48,刚好得到的就是输入的数原创 2021-07-31 08:58:43 · 8398 阅读 · 0 评论 -
C——i++和++i到底有什么区别
好了经过研究上述四种情况,就可以下结论:**所以如果在while中或者for的主体部分使用`++`,必须按照其定义来。但是如果在for的判断部分使用,就没有区别。**原创 2021-08-14 15:41:23 · 154 阅读 · 0 评论 -
C——自动变量(automatic variable)、静态变量(static variable)和寄存器变量(register variable)
在C语言中,变量有三种类型:自动变量(automatic variable)、静态变量(static variable)和寄存器变量(register variable),他们大部分地方都是相似的,但是每个都有各自的特性。原创 2021-12-13 16:34:32 · 9738 阅读 · 4 评论 -
C——预处理器(Preprocessor)和宏替换(Macro Substitution)以及其他特性的使用和注意事项
C语言的预处理器(Preprocessor)理论上是编译的第一步,通过预处理器来提供了一些特性,例如宏、使用`##`串联参数、条件包含(Conditional Inclusion)等。C中提供了宏替换(Macro Substitution)的使用,宏的作用域是从#define到文件结束。尽管这个宏看起来很像函数调用,但是max(A, B)使用的时候会扩展成内连代码(也就是编译的时候,编译器会在这写上这写代码,然后编译,而不是调用一个函数)所以需要注意,宏在使用的时候带参数,会运行两次。尽管如此,这个“陷阱”原创 2021-12-16 16:56:27 · 1264 阅读 · 0 评论