和  的作用是什么?

我期望这行简单的代码 printf("foo\b\tbar\n"); 将"o"替换为"\t"并产生以下输出 fo bar (假设制表位每 8 个字符出现一次)。 foo bar 看来我的 shell 将 \b 解释为"将光标向后移动一个位置",将 \t 解释为"将光标移动到下一个制表位"。 答案 退格键和制表符都可以移动光标位置。 你的代码说: 打印"富" 将光标向后移动一格 将光标向前移动到下一个制表位 输出"条"。 为了获得您期望的输出,您需要printf("foo\b \tbar")。 输出"富" 将光标向后移动一格 输出一个" “(这取代了第二个"o”)。 将光标向前移动到下一个制表位 输出"条"。 大多数时候,使用制表符和退格键来格式化程序输出是不合适的。printf()格式说明符。 这个小脚本展示了一种改变终端选项卡渲染的方法。 #!/bin/bash tabs -8 echo -e "\tnormal tabstop" for x in `seq 2 10`; do tabs $x echo -e "\ttabstop=$x" done tabs -8 echo -e "\tnormal tabstop" 另请参阅man setterm和regtabs。 如果您重定向输出或仅写入文件,制表符通常会显示为少于标准 8 个字符,尤其是在"编程"编辑器和 IDE 中。 换句话说: printf("%-8s%s", "foo", "bar"); /* this will ALWAYS output "foo bar" */ printf("foo\tbar"); /* who knows how this will be rendered */ 恕我直言,一般来说,选项卡很少适用于任何事情。...

__attribute__((constructor)) 到底是如何工作的?

看起来很清楚它应该设置一些东西。 具体什么时候运行? 为什么有两个括号? 是__attribute__一个函数? 这在 C 中有效吗? 它所使用的函数是否需要是静态的? 什么时候__attribute__((destructor))跑步? Objective-C 中的示例: __attribute__((constructor)) static void initialize_navigationBarImages() { navigationBarImages = [[NSMutableDictionary alloc] init]; } __attribute__((destructor)) static void destroy_navigationBarImages() { [navigationBarImages release]; } 答案 它在加载共享库时运行,通常是在程序启动期间。 所有 GCC 属性都是如此; GCC 特定语法。 是的,这适用于 C 和 C 。 不,该函数不需要是静态的。 析构函数在共享库卸载时运行,通常在程序退出时运行。 因此,构造函数和析构函数的工作方式是共享对象文件包含特殊部分(ELF 上的 .ctors 和 .dtors),其中包含对分别用构造函数和析构函数属性标记的函数的引用。 想想看,普通的静态链接器中可能存在一些类似的魔力,因此无论用户选择静态还是动态链接,在启动/关闭时都会运行相同的代码。 来自: stackoverflow.com

__file__宏显示完整的路径

标准的预定宏__FILE__C 中可用显示文件的完整路径。 /full/path/to/file.c 我懂了 to/file.c 或者 file.c 答案 尝试 #include <string.h> #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) 对于 Windows,请使用"\\“而不是”/"。 来自: stackoverflow.com

__stdcall是什么?

我正在学习Win32编程,以及WinMain原型如下: int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show ) 我对此感到困惑WINAPI标识符是和发现的: #define WINAPI __stdcall 这做什么?我对返回类型后完全有一些东西感到困惑。什么是__stdcall为了?当返回类型和函数名称之间存在某些内容时,这是什么意思? 答案 __stdcall是用于该功能的呼叫约定。这告诉编译器,适用于设置堆栈,推动参数并获得返回值的规则。 还有许多其他调用约定,__cdecl,,,,__thiscall,,,,__fastcall和奇妙的名字__declspec(naked)。__stdcall是 Win32 系统调用的标准调用约定。 维基百科涵盖了细节。 当您调用代码之外的函数(例如OS API)或OS正在调用您时,这主要重要(就像Winmain一样)。如果编译器不知道正确的呼叫约定,那么您可能会遇到非常奇怪的崩溃,因为堆栈将无法正确管理。 来自: stackoverflow.com

_DEBUG 与 NDEBUG

应使用哪个预处理器定义来指定代码的调试部分? 使用#ifdef _DEBUG或者#ifndef NDEBUG或者有更好的方法来做到这一点,例如#define MY_DEBUG? 我认为_DEBUG是 Visual Studio 特定的,NDEBUG 是标准的吗? 答案 Visual Studio 定义_DEBUG当您指定/MTd或者/MDd选项,NDEBUG禁用标准 C 断言。_DEBUG如果你希望你的调试代码与MS CRT 调试技术和NDEBUG如果你想保持一致assert()。 如果您定义自己的调试宏(并且不会破解编译器或 C 运行时),请避免以下划线开头的名称,因为它们是保留的。 来自: stackoverflow.com

-> C 结构的类型参数无效

我正在尝试访问一系列结构中的项目,并按照以下方式打印结构字段 printList(Album *a, int numOfStructs) { int i; int j; for(i = 0; i < numOfStructs; i++) { printf("number%d\n:", i+1); printf("%s", a[i]->field2); printf("%s", a[i]->field2); printf("%d", a[i]->field3); for(j = 0; j < a[i]->numOfStrings; j++) { printf("%s", a[i]->strings[j]); } printf("\n"); } } 但我收到了很多这样的错误 " - >“的无效类型参数 我用这个指针做错了什么? 答案 a是类型Album*意思就是a[i]是类型Album(它是i阵列中的元素Album对象指向a)。 左操作数->必须是指针;这.如果不是指针,则使用操作员。 来自: stackoverflow.com

...链接器错误的多重定义

我定义了一个特殊文件:config.h 我的项目也有文件: t.c, t.h pp.c, pp.h b.c b.h l.cpp and #includes: in t.c: #include "t.h" #include "b.h" #include "pp.h" #include "config.h" in b.c: #include "b.h" #include "pp.h" in pp.c: #include "pp.h" #include "config.h" in l.cpp: #include "pp.h" #include "t.h" #include "config.h" 我没有包含指示*.h文件,仅在*.c文件。我在config.h: const char *names[i] = { "brian", "stefan", "steve" }; 并且需要在L.CPP,T.C,pp.c中的数组,但我会遇到此错误: pp.o:(.data+0x0): multiple definition of `names' l.o:(.data+0x0): first defined here t.o:(.data+0x0): multiple definition of `names' l.o:(.data+0x0): first defined here collect2: ld returned 1 exit status make: *** [link] Error 1 我每个人都包括后卫*....

.c vs .cc vs. .cpp vs .hpp vs .h vs .cxx

Possible Duplicates: *.h或 *.hpp for您的班级定义 C 代码文件扩展名正确吗? 我曾经以为曾经是这样的: .h文件是C和C ++的标头文件,通常仅包含声明。 .c文件是C源代码。 .cpp文件是C ++源代码(也可以是C源代码)。 然后像文件一样.hpp,,,,.cc, 和.cxx来了,我完全感到困惑…这些区别有什么区别?您什么时候使用"新"? 答案 从历史上看,C ++使用的第一个扩展是.c和.h,与C完全一样,这引起了实际问题,尤其是.c这不允许构建系统轻松区分C ++和C文件。 开发了C ++的Unix具有案例敏感的文件系统。所以有些使用.C对于C ++文件。其他使用.c++,,,,.cc和.cxx。.C和.c++有一个问题是它们在其他文件系统上没有可用,并且使用迅速下降。DOS和Windows C ++编译器倾向于使用.cpp,其中一些使选择很难(即使不是不可能)进行配置。便携性考虑使该选择最常见,即使是MS-Windows之外也是如此。 标题已经使用了相应的.H,,,,.h++,,,,.hh,,,,.hxx和.hpp。.h至今仍是C ++的流行选择,即使缺点,它不允许知道标头是否可以包含在C上下文中。现在,标准标头完全没有扩展。 另外,有些正在使用.ii,,,,.ixx,,,,.ipp,,,,.inl对于提供内联定义的标题和.txx,,,,.tpp和.tpl对于模板定义。这些要么包含在提供定义的标题中,要么在需要的上下文中手动。 编译器和工具通常不在乎使用了哪些扩展名,但是使用它们与C ++关联的扩展程序可防止需要跟踪如何配置它们,从而正确识别使用的语言。 2017编辑:Visual Studio的实验模块支持.ixx作为模块接口的默认扩展名,Clang ++正在识别.c++m,,,,.cppm和.cxxm出于相同的目的。 来自: stackoverflow.com

.c和.h文件扩展对C意味着什么?

这全都在标题中;我认为超级简单,但是很难在任何地方搜索句法事物。 这是我从中复制的两个库文件CS50网,我想知道为什么他们有两个不同的扩展。 答案 .c:c文件(实际上是真正的动作,通常) .h:标头文件(将与预处理器一起包含#include指示)。包含通常被认为与代码其他部分共享的内容,例如函数原型,#定义内容,全局变量的外部声明(哦,恐怖)等。 从技术上讲,您可以将所有内容都放在一个文件中。整个C程序。百万线。但是我们人类倾向于组织事物。因此,您可以创建不同的C文件,每个文件包含特定功能。一切都很好干净。然后突然你意识到declaration您可以进入给定的C文件中,也应该存在于另一个C文件中。因此,您会复制它们。因此,最好的是提取声明并将其放入公共文件中,即.h 例如,在CS50.H中,您可以找到您功能的"正向声明"。向前声明是一种告诉编译器应如何调用函数(例如输入参数)及其返回的函数的快速方法会抱怨)。 另一个例子。假设您编写一个.c文件,该文件包含执行正则表达式匹配的函数。您希望您的功能接受正则表达式,匹配的字符串以及一个告诉比较是否必须不敏感的参数。 因此,在.c中,您将放置 bool matches(string regexp, string s, int flags) { the code } 现在,假设您要传递以下标志: 0:如果搜索是案例敏感的 1:如果搜索是不敏感的 并且您想让自己对新标志保持开放,因此您没有输入布尔值。 #define MATCH_CASE_SENSITIVE 0 #define MATCH_CASE_INSENSITIVE 1 此信息进入了.H,因为如果任何程序都想使用这些标签,除非包含信息,否则它无法了解它们。当然,您可以将它们放入.C中,但是您必须包括.c代码(整个!),这是浪费时间和麻烦的根源。 来自: stackoverflow.com

'

Possible Duplicates: While 与 Do While 我什么时候应该使用do-而不是循环? 我已经编程了一段时间(2年工作 + 4。5年 + 1年的预科课程),而且我从未在编程课程中被迫被迫使用过的循环。如果我从来没有遇到如此基本的事情,我越来越感到自己正在做错了编程。 难道我只是没有遇到正确的情况吗? 有哪些示例有必要使用DO-DO-nier而不是一段时间? (我的教育几乎全部都在C/C ++中,我的工作在C#中,因此,如果另一种语言绝对有意义,因为Do-whiles的工作方式有所不同,那么这些问题并不适用)。 澄清…我知道while和do-while。在检查退出条件并执行任务时。do-while执行任务,然后检查退出条件。 答案 如果您始终希望循环至少执行一次。这并不常见,但是我会不时使用它。您可能想使用它的一种情况是尝试访问可能需要重试的资源,例如 do { try to access resource... put up message box with retry option } while (user says retry); 来自: stackoverflow.com

' ' 转义序列有什么用?

我有这样的C代码: #include<stdio.h> int main() { printf("Hey this is my first hello world \r"); return 0; } 我已经用过\r转义序列作为实验。 o world 这是为什么,有什么用\r到底是什么? 如果我在一个在线运行相同的代码编译器得到的输出为: Hey this is my first hello world 为什么在线编译器会产生不同的输出,忽略\r? 答案 \r是一个回车特点; 这光标是渲染下一个字符的位置。 所以,打印一个\r允许覆盖终端仿真器的当前行。 汤姆·齐奇弄清楚为什么你的程序的输出是o world而\r位于该行的末尾,之后您不会打印任何内容: 当程序退出时,shell 会打印命令提示符。o world。 这在线编译器 您提到的只是将原始输出打印到浏览器。\r没有影响。 看https://en.wikipedia.org/wiki/Carriage_return 这是一个使用示例\r: #include <stdio.h> #include <unistd.h> int main() { char chars[] = {'-', '\\', '|', '/'}; unsigned int i; for (i = 0; ; ++i) { printf("%c\r", chars[i % sizeof(chars)]); fflush(stdout); usleep(200000); } return 0; } 它重复打印字符- \ | /在同一位置,给人一种旋转的错觉|在终端中。...

'\0' 的 ASCII 值与 0 的 ASCII 值相同吗?

我了解到 ‘\0’ 的 ASCII 值是 0,0 的 ASCII 值是 0x30,但是当我尝试使用 printf 打印它们的 ASCII 值时,我得到相同的输出: printf("\'\\0\' : %d\n", '\0'); printf("\'\\0\' in hex : %x\n", '\0'); printf("0 : %d\n", 0); printf("0 in hex: %x\n", 0); 输出: '\0' : 0 '\0' in hex : 0 0 : 0 0 in hex: 0 为什么? 答案 ASCII 字符'0'与数字不同0。0在你的第二对printfs 而不是'0'。 尝试这个: printf("'\\0' : %d\n", '\0'); printf("'\\0' in hex : %x\n", '\0'); printf("'0' : %d\n", '0'); printf("'0' in hex: %x\n", '0'); 而且,你不需要逃避'字符串内部。"'"很好,你不需要写"\'"...

'float'vs.“双”精度

代码 float x = 3.141592653589793238; double z = 3.141592653589793238; printf("x=%f\n", x); printf("z=%f\n", z); printf("x=%20.18f\n", x); printf("z=%20.18f\n", z); 会给你输出 x=3.141593 z=3.141593 x=3.141592741012573242 z=3.141592653589793116 在第三行输出处的位置741012573242是垃圾,在第四行116是垃圾。双打总是有16个重要数字,而浮子总是有7个重要数字?为什么双打没有14个重要数字? 答案 C中的浮点数使用IEEE 754编码。 这种类型的编码使用符号,一个显着性和指数。 由于此编码,许多数字将具有很小的更改以允许它们存储。 同样,由于它是二进制表示,而不是十进制的数字,因此重要数字的数量可能会稍微改变。 单个精度(浮点)为您提供23位显着的,8位指数和1个符号位。 双精度(双重)为您提供52位显着性,11位指数和1个符号位。 来自: stackoverflow.com

'sprintf':C中的双重精度

考虑: double a = 0.0000005l; char aa[50]; sprintf(aa, "%lf", a); printf("%s", aa); Output: s0.000000 在上面的代码段中,变量aa只能包含六个小数的精度。我想获得" S0.000055"之类的输出。我该如何实现? 答案 从您的问题看,您似乎正在使用C99%lf双重。 为了实现所需的输出替换: sprintf(aa, "%lf", a); 和 sprintf(aa, "%0.7f", a); 一般语法"%A.B"小数点后使用B位数的方法。含义A更复杂,但可以阅读这里。 来自: stackoverflow.com

“ {'token”之前的预期表达

因此,当我尝试将值分配给INT数组时,我会继续遇到这个问题。我读了这个预期的表达" {“令牌,但我仍然对为什么它在我的代码中显示。我有一种感觉,我正在初始化并声明阵列不正确,这就是为什么它给出了我的问题。 因此,在main()我宣布某些全球变量之前(是的,我知道这很危险,但是出于我的目的而需要)。对于那组全球变量,我也想声明一个大小3的双重数组 double rob_size, rob_tilt; double rob_leftcolor [3]; double rob_rightcolor [3]; 然后在主要函数中,我正在初始化变量和数组 rob_size = 1.0; rob_tilt = 0.0; rob_leftcolor [3] = {1.0, 0.0, 0.0}; rob_rightcolor [3] = {0.0, 1.0, 0.0}; 但是,我在” {’token" at之前收到"预期表达式"的错误消息。 首先,该错误消息是什么意思?其次,因为我正在不正确地宣布阵列并声明阵列是因为我会出现这个消息吗? 谢谢 答案 最好在声明时间进行初始化: double rob_size = 1.0; double rob_tilt = 0.0; double rob_leftcolor [3] = {1.0, 0.0, 0.0}; double rob_rightcolor [3] = {0.0, 1.0, 0.0}; 只有数组need这样做,但是最好以同样的方式进行操作。 您的选择是 rob_leftcolor[0] = 1.0; rob_leftcolor[1] = 0.0; rob_leftcolor[2] = 0....