
C/C++
文章平均质量分 81
编程语言C++的知识系列。
以Android性能优化实战为线索,以性能优化项目代码为切入点。由点到面深入C/C++个环节,提高工程化编码能力和思维能力。
程序员-薯片
公众号【程序员薯片】
专注于:
1.AI+应用实战研究&开发。
2.码农中年危机自救指南研究&探索。
3.码农视觉的读书感悟&分享。
展开
-
【C/C++ API】C++内存分配和释放函数分析
是一个 C 语言函数,用于分配一块内存,并保证返回的指针地址满足特定的对齐要求。指向的内存块,并使该内存块可用于后续的内存分配。字节,并返回一个指向重新分配后的内存块的指针。之后,我们检查是否分配成功,然后使用该内存,最后在不再需要时释放该内存。是 C 标准库中的一个函数,用于分配一块内存,并保证返回的指针地址满足特定的对齐要求。是 C 标准库中的一个函数,用于重新分配先前分配的内存块的大小。,即要释放的内存块的指针。是 C 标准库中的一个函数,用于动态分配内存,并将分配的内存空间初始化为零。原创 2024-03-11 15:41:08 · 1250 阅读 · 0 评论 -
【C++】namespace命名空间
匿名命名空间是 C++ 中的一种特殊的命名空间,它没有名称,用于限定其中声明的变量、函数和类的作用域。通常情况下,匿名命名空间适用于那些在当前文件中定义的具有局部作用域的变量、函数、类等,而不需要在其他文件中引用或者暴露给外部的情况。在匿名命名空间中声明的变量、函数、类等只在当前源文件中可见,不能被其他源文件访问,所以不会与其他文件中的同名符号发生冲突。:在匿名命名空间中声明的变量、函数、类等的作用域被限制在当前文件中,对其他文件不可见。的命名空间,包含了一个整型变量。来访问命名空间中的成员。原创 2024-02-07 14:29:48 · 443 阅读 · 0 评论 -
C/C++ extern关键字
当一个变量或函数在多个文件中使用时,原创 2023-12-14 22:55:21 · 179 阅读 · 0 评论 -
C语言中的格式化输出符号:%d %c %p %x等
d是C语言中的格式化输出符号,用于将整数值按照十进制格式输出到标准输出流(通常是控制台)。它可以用于printf函数中的格式化字符串中,指示要输出的整数的位置和格式。例如,"%d"可以用来输出一个整数变量的值。%c是C语言中的格式化输出符号,用于输出字符。在printf函数中,%c可以用来输出一个字符变量的值。在你的代码中,如果你想打印出数组元素的字符表示,你可以使用%c。在C语言中,%p是一种格式化输出的转换说明符,用于打印指针变量的值。输出其他类型的数据,将会导致未定义的行为。类型的数据,如果使用。原创 2023-12-01 11:39:41 · 53205 阅读 · 1 评论 -
C/C++转义符:\x
\:反斜杠符号\':单引号\":双引号\a:响铃符号(ASCII 值为 7)\b:退格符号(ASCII 值为 8)\f:换页符号(ASCII 值为 12)\n:换行符号(ASCII 值为 10)\r:回车符号(ASCII 值为 13)\t:水平制表符号(ASCII 值为 9)\v:垂直制表符号(ASCII 值为 11)如下图:可以在字符串中使用这些转义符,表示相应的特殊字符,例如用\n表示一个换行符。从C90 开始,C提供了第三种选择,即使用十六进制形式表示字符常量。原创 2023-11-30 15:26:27 · 2984 阅读 · 0 评论 -
链接2:静态链接、目标文件、符号和符号表
由m定义并能被其他模块引用的全局符号。全局链接器符号对应于非静态的 C 函数以及被定义为不带 C的 static 属性的全局变量。由其他模块定义并被模块 m引用的全局符号。这些符号称为外部符号 (exteal),对应于定义在其他模块中的 C函数和变量。只被模块 m 定义和引用的本地符号。有的本地链接器符号对应于带 static 属性的 C 函数和全局变量。这些符号在模块 m 中的任何地方都是可见的,但是不能被其他模块引用。目标文件中对应于模块 m 的节和相应的源文件的名字也能获得本地符号。原创 2023-11-28 23:16:30 · 474 阅读 · 0 评论 -
链接1:编译器驱动程序
GCC的设计目标之一是提供高度的可移植性,使得开发者可以在不同的平台上使用相同的源代码进行编译。shell 调用操作系统中一个叫做加载器(loader)的函数,它将可执行文件 prog 中的代码和数据复制到内存,然后将控制转移到这个程序的开头。这个命令使用GCC编译器,它的目标是将两个C语言源代码文件(main.c和sum.c)编译成一个可执行文件,该文件的名称将被命名为“prog”。这个命令将执行编译操作,生成一个名为“prog”的可执行文件,其中包含来“main.c”和“sum.c”的源代码。原创 2023-11-28 21:58:41 · 159 阅读 · 0 评论 -
C语言中#ifndef的头文件保护用法和宏定义用法
1这段代码是为一个错误码定义了一个宏。如果在之前的代码中没有定义_error,则会定义_error宏,并赋值为 -1。如果在之前的代码中已经定义了_error,则这个宏定义将被忽略。原创 2023-11-27 18:41:54 · 861 阅读 · 0 评论 -
C的内联函数(C99)
file2.c 文件中是普通的函数定义(因此具有外部链接);原创 2023-11-16 20:42:31 · 338 阅读 · 0 评论 -
C/C++预定义宏、 #line 、#error、 #pragma和泛型选择
_func_ _C99 标准提供一个名为_ _func_ _的预定义标识符,它展开为一个代表函数名的字符串(该函数包含该标识符)。那么,_ _func__必须具有函数作用域,而从本质上看宏具有文件作用域。因此,_ _func_ _是C语言的预定义标识符,而不是预定义宏。下面程序中使用了一些预定义宏和预定义标识符。注意,其中一些是C99 新增的,所以不支持C99的编译器可能无法识别它们。如果使用GCC,必须设置-std=c99或-std=c11。原创 2023-11-16 18:07:15 · 827 阅读 · 0 评论 -
C/C++条件编译:#ifdef、#else、#endif等
标识符可以由大写字母、小写字母、数字和下划线字符组成且首字符不能是数字。当预处理器在预处理器指令中发现一个标识符时,它会把该标识符当作已定义的或未定义的。这里的已定义表示由预处理器定义。如果标识符是同一个文件中由前面的#define指令创建的宏名,而且没有用#undef 指令关闭,那么该标识符是已定义的。如果标识符不是宏,假设是一个文件作用域的C变量,那么该标识符对预处理器而言就是未定义的。1000// LIMIT是已定义的#define GOOD // GOOD 是已定义的。原创 2023-11-16 15:56:47 · 10272 阅读 · 2 评论 -
C/C++ #include
—标准I/O函数使用FILE结构,该结构中包含了文件和与文件缓冲区相关的信息。FILE结构在头文件stdio.h中。——标准 I/O 函数使用指向 FILE 的指针作为参数。通常,stdio.h 用#define 或typedef把FILE定义为指向结构的指针。类似地,size_t和time_t类型也定义在头文件中。许多程序员都在程序中使用自己开发的标准头文件。如果开发一系列相关的函数或结构,那么这种方法特别有价值。原创 2023-11-16 14:45:04 · 270 阅读 · 0 评论 -
C/C++宏和函数的选择
有些编程任务既可以用带参数的宏完成,也可以用函数完成。应该使用宏还是函数?这没有硬性规定,但是可以参考下面的情况。原创 2023-11-16 10:21:27 · 126 阅读 · 0 评论 -
C/C++ #运算符、##运算符、变参宏 ...和_ _VA_ARGS_ _
成为描述这种工具的通用词(虽然,C标准的索引添加了字符串化(stringizing)词条,但是,标准并未把固定参数的函数或宏称为固定函数和不变宏)。例如,如果x是一个宏形参,那么#x就是转换为字符串"x"的形参名。注意双引号字符串中的X被视为普通文本,而不是一个可被替换的记号。程序演示了一个示例,该程序使用了字符串的串联功能和#运算符。与#运算符类似,##运算符可用于类函数宏的替换部分。第1个宏调用,X的值是1,所以#X变成"1"。而且,##还可用于对象宏的替换部分。调用第1个宏时,用"y"替换#x。原创 2023-11-14 16:03:42 · 441 阅读 · 0 评论 -
C/C++:在#define中使用参数
导致这样结果的原因是,我们前面提到过,预处理器不做计算、不求值,只替换字符序列。现在SQUARE(x+2)变成了(x+2)*(x+2),在替换字符串中使用圆括号就得。SQUARE(++x)变成了++x*++x,递增了两次x,一次在乘法运算之前,一次。这里,SQUARE 是宏标识符,SQUARE(X)中的 X 是宏参数,X。参数的宏看上去很像函数,因为这样的宏也使用圆括号。面的示例不同,使用该宏时,既可以用X,也可以用其他符号。5,你可能认为SQUARE(x+2)应该是 7*7,即 49。原创 2023-11-13 18:47:01 · 569 阅读 · 0 评论 -
C/C++ #define与编译器的预处理
我们大量使用#define指令来定义明示常量(manifest constant)(也叫做符号常量),但是该指令还有许多其他用途。以下程序演示了#define指令的一些用法和属性。预处理器指令从#开始运行,到后面的第1个换行符为止。也就是说,指令的长度仅限于一行。然而,前面提到过,在预处理开始前,编译器会把多行物理行处理为一行逻辑行。/* preproc.c -- 简单的预处理示例 */2/* 可以使用注释 */tive.- Oscar Wilde" /* 反斜杠把该定义延续到下一行 */原创 2023-11-13 18:44:20 · 150 阅读 · 0 评论 -
C++内联函数
执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈(为此保的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入到寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。这里的目的不是演示如何编写C 宏,而是要指出,如果使用 C语言的宏执行了类似函数的功能,应考虑将它们转换为 C++内联函数。但是程序中的内联函数 square()计算c的结果,传递它,以计算其平方值,然后将c递增一次。原创 2023-11-13 11:39:28 · 101 阅读 · 0 评论 -
C++一图看懂指针常量、常量指针、指向常量的常指针、野指针、空指针
先是一个指针int * , 然后一个常量const ,那么p就是指针常量。先是一个const常量, 然后是一个int *指针, 那么p就是常量指针。原创 2023-11-10 14:54:34 · 109 阅读 · 0 评论 -
C++函数指针
函数的地址是存储其机器语言代码的内存的开始地址。通常,这些地址对用户而言,既不重要,也没有什么用处,但对程序而言,却很有用。例如,可以编写将另一个函数的地址作为参数的函数。提示: 通常,要声明指向特定类型的函数的指针,可以首先编写这种函数的原型,然后用(*pf) 替换函数名。由于 pam 是函数,因此(*pf)也是函数。这意味着声明应指定函数的返回类型以及函数的特征标(参数列表)。运算符高,因此*pf(int)意味着pf()是一个返指的函数。同样,声明指向函数的指针时,也必须指定指针指向的函数类型。原创 2023-11-10 16:09:12 · 84 阅读 · 0 评论 -
C++函数原型和函数调用
首先,原型告诉编译器,cube()有一个 double 参数。如果程序没有提供这样的参数,原型将让编译器能够捕获这种错误。其次,cube()函数完成计算后,将把返回值放置在指定的位置一一可能是 CPU 寄存器也可能是内存中。然后调用函数 (这里为 main))将从这个位置取得返回值。由于原型指出了 cube()的类型为 double,因此编译器知道应检索多少个字节以及如何解释它们。如果没有这些信息,编译器将只能进行猜测,而编译器是不会这样做的。原创 2023-11-09 10:51:12 · 107 阅读 · 0 评论 -
C++函数参数和按值传递
这还意味着,如果在 main()中声明了一个名为side的变量,同时在另一个函数中也声明了一个名为x的变量,则它们将是两个完全不同的、毫无关系的变量,这与加利福尼亚州的 AIbany 与纽约的 Albany 是两个完全不同的地方是一样的道理,因为它们是在程序执行过程中自动被分配和释放的。这样,cube()执行的操作将不会影响 main()中的数据,因为 cube()使用的是 side 的副本,而不是原来的数据。在函数被调用时,计算机将为这些变量分配内存在函数结束时,计算机将释放这些变量使用的内存。原创 2023-11-09 11:30:46 · 77 阅读 · 0 评论 -
C++以数组作为参数,传递数组地址
然而,数组表示法 (int arr[]) 提醒用户,arr 不仅指向 int,还指向 int 数组的第一个int。其中,cookies 是数组名,而根据 C++规则,cookies 是其第一个元素的地址,因此函数传递的是地址由于数组的元素的类型为 int,因此 cookies 的类型必须是 int 指针,即 int*。第三,将地址运算符&用于数组名时,将返回整个数组的地址,例如&cookies 将返回一个32 字节内存块的地址(如果int长4字节)但传递数组时,函数将使用原来的数组。原创 2023-11-10 11:04:47 · 605 阅读 · 0 评论