中文名:你必须知道的495道C语言题高清PDF中文版 原名:C FAQs 作者:(美国)Samit 译者:孙云朱群英 资源格式:PDF版:扫描版 出版社:人民邮电出版社 ISBN:发布日期发布时间:2009年2月1日 地区:中国大陆 语言:简体中文 简介:内容介绍 本书以问答的形式组织内容,讨论了学习或使用C语言过程中经常遇到的一些问题。 书中列出了400多个C用户经常提出的经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预处理器等各种主题,并分别提供了答案。 并结合代码示例来说明要点。 本书结构清晰,讲解透彻。 是高等院校相关专业C语言课程很好的教学参考书,也是各级C程序员的优秀实践指南。 作者简介:Steve,著名C语言专家。 C FAQ 的创始人和维护者拥有近 30 年的 C 编程经验。 毕业于麻省理工学院。 他在华盛顿大学教授C语言课程多年。 除了本书之外,他还与人合着了《C》一书,编辑推荐全世界C语言程序员集体智慧的结晶。 一本五星级的书,对 495 个最常见的 C 语言问题进行了权威解答。 C是一门简洁而精致的语言。 掌握基本语法很容易。 能够自由使用并不是那么简单的事情。 。
你不可避免地会遇到各种各样的问题,其中有些问题可能会让你感到困惑。 您甚至可以搜索图书馆,但仍然找不到答案。 《495个你必须知道的C语言问题》的出版填补了这一空白。 书中的内容是世界各地C语言用户在新闻组comp.1ang.c中多年讨论的结果。 作者对在线版CFAQ列表进行了极大的扩充和丰富,结合代码示例,对实际学习和工作中最常遇到的495个C语言问题进行了权威详细的解答,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C 预处理器等各个方面的主题。 很多知识点的讲解是其他资料中没有的,非常珍贵。 涵盖C99标准》这本书是C FAQ在线列表许多贡献者多年努力的结晶,是C语言社区最珍贵的瑰宝之一。我向所有C语言推荐这本书程序员。” ——,著名C/C++专家,ACCU(C/C++用户协会)前主席“这本书清楚地解释了书中许多简单的地方。C语言编程实践也精彩总结。强烈推荐!” —— M ., :第一章声明和初始化基本类型 1.1 如何决定使用哪种整数类型? 1.2 为什么不精确定义标准类型的尺寸? 1.3 由于C语言没有准确定义类型的大小,所以我通常定义int16和int32。
然后根据实际机器环境将其定义为int、short、long等类型。 似乎所有的问题都解决了,对吧? 1.4 64 位类型在新的 64 位机器上是什么样子? 指针声明 1.5 这样的声明有什么问题吗? 字符 *p1, p2; 我在使用p2时遇到错误。 1.6 我想声明一个指针并为其分配一些空间,但我不能。 这样的代码有什么问题吗? 字符*p; *p=(10);声明风格 1.7 声明和定义全局变量和函数的最佳方式是什么? 1.8 如何在C 中实现不透明(抽象)数据类型? 1.9 如何生成“半全局变量”,即只能被某些源文件中的某些函数访问的变量? 存储类型 1.10 同一 () 函数或变量的所有声明都必须包含存储类型吗? 1.11 函数声明中的含义是什么? 1.12 关键字auto有什么用? 类型定义()1.13 对于用户自定义类型,和#有什么区别? 1.14 我似乎无法成功定义链表。 我尝试过 {char *item; 下一个;}* ; 但编译器报了错误信息。
C语言中的结构体不能包含指向自身的指针吗? 1.15 如何定义一对互相引用的结构体? 1.16 两个声明 { } x1; 有什么区别和 { } x2;? 1.17 “int(*)();”是什么意思意思是? const 限定符 1.18 我有这样一组声明: char *charp; const charp p; 为什么 p 是 const 而不是它指向的字符? 1.19 为什么我们不能像下面这样在初始化器和数组维度值中使用const值? 常量整数n=5; int a[n];1.20 const char *p、char const *p 和 char *const p 之间有什么区别? 复杂语句 1.21 如何创建和理解非常复杂的语句? 例如定义一个包含 N 个指向函数的指针的数组,这些函数返回指向字符的指针? 1.22 如何声明一个返回相同类型函数指针的函数? 我正在设计一个状态机,其中每个状态都由一个函数表示,每个函数返回一个指向下一个状态的函数的指针。 但我找不到任何方法来声明这样的函数 - 感觉就像我需要一个返回指针的函数,并且返回的指针指向返回指针的函数,依此类推,无穷无尽。
数组大小 1.23 我可以声明一个与传入数组大小相同的本地数组,或者一个大小由其他参数指定的参数数组吗? 1.24 我在一个文件中定义一个数组,然后在另一个文件中使用它。 为什么我无法获取数组的大小? 声明问题1.25 函数只定义一次,调用一次,但编译器提示非法重新声明。 1.26 main 的正确定义是什么? void main 正确吗? 1.27 我的编译器总是报函数原型不匹配错误,但我认为没有问题。 这是为什么? 1.28 文件中的第一条语句报告了一个奇怪的语法错误,但我没有发现它有什么问题。 这是为什么? 1.29 为什么我的编译器不允许我定义大数组,例如 array[256][256]? 命名空间 1.30 如何确定哪些标识符可以使用,哪些标识符保留? 初始化 1.31 对于未显式初始化的变量的初始值可以做出哪些假设? 如果全局变量以“零”初始化,它可以用作空指针或浮点零吗? 1.32 为什么下面的代码无法编译? intf(){char a[]="Hello, world!";}1.33 下面的初始化有什么问题? 编译器提示“ ”或其他信息。 char *p=(10);1.34 char a[]= " "; 和 char *p=" "; 初始化有什么区别? 当我给 p[i] 赋值时,我的程序崩溃了。
1.35 字符a{[3]}=“abc”; 合法吗? 1.36 我终于知道如何声明函数指针了,但是如何初始化它呢? 1.37 联合体可以初始化吗? 第二章 结构体、联合体和枚举结构声明 2.1 x1{ }; 之间的区别是什么和 { }x2;? 2.2 为什么这段代码是错误的? X{ }; x ;2.3 结构体可以包含指向自身的指针吗? 2.4 用C语言实现抽象数据类型的最佳方法是什么? 2.5 有没有好的方法可以在C中模拟继承等面向对象编程特性? 2.6 为什么语句 f( x *p); 给我一条晦涩的警告信息? 2.7 我遇到了声明如下结构的代码:name {int; 字符[1];}; 然后使用一些内存分配技术使数组看起来像有多个元素,并记录元素的数量。 它是如何工作的? 这合法且可移植吗? 2.8 我听说结构体可以赋值给变量,也可以传入传出函数。 为什么 K&R1; 明确表示不能这样做? 2.9 为什么我们不能使用内置的 == 和 != 运算符来比较结构? 2.10 结构转移和回归是如何实现的? 2.11 如何将常量值传递给接受结构体参数的函数? 如何创建无名中间常量结构值? 2.12 如何从数据文件读取结构或向数据文件写入结构? 结构填充 2.13 为什么我的编译器会在结构中留下漏洞? 这会导致空间浪费,并且无法对外部数据文件进行“二进制”读写。
我可以关闭填充或控制域的对齐方式吗? 2.14 为什么返回值大于结构体大小的预期值? 末尾有填充吗? 2.15 如何确定结构体中字段的字节偏移量? 2.16 如何在运行时按名称访问结构体中的字段? 2.17 C语言中是否有相当于with的语句? 2.18 既然数组名可以用作数组的基地址,为什么结构体不能这样做? 2.19 程序运行正常,但退出时出现“core dumps”。 这是怎么回事? Union 2.20 结构体和联合体有什么区别? 2.21 有没有办法初始化联合体? 2.22 是否有一种自动方法来跟踪正在使用的联合域? 枚举 2.23 枚举和一组预处理的#有什么区别? 2.24 枚举是否可移植? 2.25 有没有简单的方法来显示枚举值的符号? 位域 2.26 某些结构声明中的这些冒号和数字是什么意思? 2.27 为什么人们更喜欢使用显式掩码和位操作而不是直接声明位域? 第 3 章 表达式求值顺序 3.1 为什么这段代码不起作用? a[i]= i++;3.2 使用我的编译器,以下代码 int i= 7; ("%d\n", i++ * i++); 打印出49。无论计算顺序如何,它不应该是56吗? 3.3 对于代码int i=3; 我=我++; 不同的编译器给出不同的i值,有些是3,有些是4,哪一个是正确的? 3.4 有这样一个巧妙的表达:a^=b^=a^=b; 它可以在没有临时变量的情况下交换a和b的值。
3.5 我可以使用显式括号来强制执行我需要的计算顺序并控制相关的副作用吗? 即使括号不起作用,运算符优先级可以控制计算顺序吗? 3.6 但是 && 和 || 又如何呢? 运营商? 我见过像 while((c = ()) != EOF && c != '\n') 这样的代码 3.7。 是否可以安全地假设一旦 && 和 || 左侧的表达式已经确定了整个表达式? 这样一来,右边的表达式就不会被求值了? 3.8 为什么表达式("%d %d", f1(), f2()); 先调用f2? 我认为逗号表达式应该确保从左到右的评估顺序。 3.9 如何理解复杂的表达式并避免编写未定义的表达式? 什么是“序列点”? 3.10 在a[i] = i++;中,如果不关心a[]的哪个部分会被写入,这段代码没有问题,i确实会加1,对吗? 3.11 人们总是说 i=i++ 的行为是未定义的。 但我只是在ANSI编译器上尝试了一下,结果正如我所料。 3.12 我不想学那些复杂的规则。 如何避免这些未定义的评估顺序问题? 其他表达式问题 3.13 ++i 和 i++ 有什么区别? 3.14 如果我不使用表达式的值,我应该使用 i++ 还是 ++i 来递增? 3.15 我想检查一个数字是否在另外两个数字之间。 为什么 if(abc) 不起作用? 3.16 为什么下面的代码不正确? 整数a=1000,b=1000; long int c=a * b;3.17 为什么下面的代码总是给出0? 摄氏度,华氏度; degC= 5.0 / 9 * (degF - 32);3.18 需要根据条件将复杂表达式分配给两个变量之一。
我可以使用下面的代码吗? (() ? a : = on;3.19 我有一些代码包含这样的表达式。 a ? b=c : d 有些编译器接受它,有些则不接受。为什么? Guard Rule 3.20 "of'' in ANSI C"警告是什么意思? 3.21 “无符号保护”和“值保护”规则有什么区别? 第四章指针基本应用 4.1 指针有什么好处? 4.2 我想声明一个指针并为其分配一些空间,但是不行。这些代码有什么问题吗? char *p; *p = (10);4.3 *p++ 是对 p 还是 p 指向的变量进行自增吗? 指针操作 4.4 我在使用指针进行操作时遇到了麻烦int 数组。4.5 我有一个 char* 指针,恰好指向一些 int 变量,我想跳过它们。为什么像 ((int *)p)++; 这样的代码不起作用?4.6 为什么不能算术对 void * 指针执行操作? 4.7 Me 一些解析外部结构的代码,但它崩溃并显示消息“ ”(未对齐访问)。这是什么意思?指针作为函数参数 4.8 我有一个应该接受的函数并初始化一个指针:void f(int *ip){ int dummy = 5; ip = &dummy;} 但是当我这样调用时: int *ip; f(IP); 调用者的指针没有任何变化。
4.9 能否使用void **通用指针作为参数来模拟函数中按引用传递参数? 484.10 我有一个函数 intf(int *); 它接受一个指向 int 的指针。 如何通过引用传递常量? 调用 f(&5); 似乎不起作用。 4.11 C语言可以“按引用传递参数”吗? 其他指针问题 4.12 我见过使用指针调用函数的不同语法形式。 发生了什么? 4.13 通用指针类型有哪些? 当我将函数指针分配给 void * 类型时,编译失败。 4.14 整数和指针如何相互转换? 是否可以将整数暂时放入指针变量中,反之亦然? 4.15 如何将 int 变量转换为 char* 类型? 我尝试过类型转换,但没有成功。 第五章 空指针 空指针和空指针常量 5.1 什么是臭名昭著的空指针? 5.2 程序中如何获取空指针? 5.3 使用缩写指针比较“if(p)”检查空指针是否有效? 如果空指针的内部表示不是 0,会发生什么? NULL 宏 5.4 什么是 NULL 以及它是如何定义的? 5.5 在使用非零位模式作为空指针内部表示的机器上如何定义 NULL? 5.6 如果NULL被定义为#NULL((char *)0),我们是否可以将NULL传递到函数中而不进行转换? 5.7 我的编译器提供的头文件中定义的NULL是0L。
为什么? 5.8 NULL 可以合法地用作函数指针吗? 5.9 如果 NULL 和 0 相当于空指针常量,我应该使用哪一个? 5.10 但是,如果 NULL 的值发生变化,例如在使用非零内部空指针的机器上,使用 NULL(而不是 0)不是更好吗? 5.11 我曾经使用过一个编译器,如果不使用 NULL 就无法编译。 5.12 我使用预处理器宏 # (type)(type *)0 来帮助创建正确类型的空指针。 复习5.13 这有点奇怪:NULL 保证为0,但空指针却不能? 5.14 为什么对空指针有这么多疑问? 为什么这些问题如此频繁地出现? 5.15 有没有更简单的方法来理解所有这些空指针的东西? 5.16 鉴于对空指针的所有这些混淆,要求它们的内部表示必须全部为 0 不是更简单吗? 5.17 说真的,有没有机器使用非零空指针,或者不同的类型使用不同的表示形式? 地址0到底是什么? 5.18 当整数值0在运行时转换为指针时,它会一直是空指针吗? 5.19 如何访问位于机器地址0的中断向量? 如果我将指针值设置为 0,编译器可能会自动将其转换为空指针的非零内部表示。 5.20 运行时出现“null”错误是什么意思? 应该如何捕捉呢? 第6 章数组和指针 数组和指针之间的基本关系 6.1 我在一个源文件中定义了 char a[6],并在另一个源文件中声明了 char *a。
为什么不? 6.2 但我听说 char a[] 和 char *a 是等价的。 是这样吗? 6.3 那么,C语言中“指针和数组是等价的”是什么意思? 6.4 既然它们如此不同,为什么作为函数参数的数组和指针声明可以互换? 数组不能赋值6.5 为什么不能用这种方式给数组赋值? 字符 *(); 字符str[10]; str=("Enter :");6.6 既然不能赋值给数组,为什么可以允许这样的代码呢? int f(char str[]){ if(str[0] == '\0') str="none";}6.7 如果不能给数组赋值,它怎么能是左值呢? 复习6.8 实际上,数组和指针有什么区别? 6.9 有人告诉我数组只是常量指针。 这准确吗? 6.10 我还是很困惑。 指针是数组类型,还是数组是指针类型? 6.11 我看到一些包含“表达式”的“有趣”代码,例如 5[""]。 为什么这是合法的 C 语言表达式? 数组指针 6.12 由于数组引用会退化为指针,如果 array 是数组,那么 array 和 &array; 有什么区别? 6.13 如何声明一个指向数组的指针? 动态数组分配 6.14 如何在运行时设置数组的大小? 如何避免固定大小的数组? 6.15 如何声明一个与传递的数组大小相同的本地数组? 6.16 如何动态分配多维数组? 6.17 一个好技巧是,如果我写: int [10]; int *数组 = &;[-1]; 我可以将“数组”视为从 1 开始的数组。
函数和多维数组 6.18 当我将二维数组传递给接受指向指针的指针的函数时,编译器报告错误。 6.19 如何编写一个接受编译时宽度未知的二维数组的函数? 6.20 传递函数参数时如何混合静态和动态多维数组? 数组的大小 6.21 当数组作为函数的参数时,为什么不能正确报告数组的大小? 6.22 如何确定在一个文件中声明的数组的大小(例如,数组定义和大小在另一个文件中)? 运营商好像不行。 6.23 返回的大小以字节为单位计算。 如何确定数组中有多少个元素? 第 7 章 内存分配 第 8 章 字符和字符串 第 9 章 布尔表达式和变量 第 10 章 C 预处理器 第 11 章 ANSI/ISO 标准 C 第 12 章 标准输入输出库 第 13 章 库函数第 14 章 浮点运算 第 15 章 可变参数列表 第 16 章 奇怪的问题 第 17 章 样式 第 18 章 工具和资源 第 19 章 系统依赖项 第 20 章 其他术语表参考