你必须知道的495个C语言问题.[美]Steve Summit(带详细书签).pdf 高清版

时间:2021-04-27 19:09:19
【文件属性】:

文件名称:你必须知道的495个C语言问题.[美]Steve Summit(带详细书签).pdf 高清版

文件大小:133.91MB

文件格式:PDF

更新时间:2021-04-27 19:09:19

C语言 C 编程 开发

  本书以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预处理器等各个方面的主题,并分别给出了解答,而且结合代码示例阐明要点。   本书结构清晰,讲解透彻,是各高校相关专业C语言课程很好的教学参考书,也是各层次C程序员的优秀实践指南。 第1章 声明和初始化 30 基本类型 30 1.1 我该如何决定使用哪种整数类型? 30 1.2 为什么不精确定义标准类型的大小? 31 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16和int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都解决了,是吗? 31 1.4 新的64位机上的64位类型是什么样的? 32 指针声明 32 1.5 这样的声明有什么问题?char *p1, p2; 我在使用p2的时候报错了。 32 1.6 我想声明一个指针,并为它分配一些空间,但却不行。这样的代码有什么问题?char *p; *p=malloc(10); 33 声明风格 33 1.7 怎样声明和定义全局变量和函数**好? 33 1.8 如何在C中实现不透明(抽象)数据类型? 34 1.9 如何生成“半全局变量”,就是那种只能被部分源文件中的部分函数访问的变量? 34 存储类型 35 1.10 同一个静态(static)函数或变量的所有声明都必须包含static存储类型吗? 35 1.11 extern在函数声明中是什么意思? 35 1.12 关键字auto到底有什么用途? 36 类型定义(typedef) 36 1.13 对于用户定义类型,typedef 和#define有什么区别? 36 1.14 我似乎不能成功定义一个链表。我试过typedef struct{char *item; NODEPTR next;}* NODEPTR; 但是编译器报了错误信息。难道在C语言中结构不能包含指向自己的指针吗? 36 1.15 如何定义一对相互引用的结构? 38 1.16 Struct{ } x1;和typedef struct{ } x2; 这两个声明有什么区别? 39 1.17 “typedef int(*funcptr)();”是什么意思? 39 const 限定词 39 1.18 我有这样一组声明:typedef char *charp; const charp p; 为什么是p而不是它指向的字符为const? 39 1.19 为什么不能像下面这样在初始式和数组维度值中使用const值?const int n=5; int a[n]; 39 1.20 const char *p、char const *p和char *const p有什么区别? 39 复杂的声明 40 1.21 怎样建立和理解非常复杂的声明?例如定义一个包含N个指向返回指向字符的指针的函数的指针的数组? 40 1.22 如何声明返回指向同类型函数的指针的函数?我在设计一个状态机,用函数表示每种状态,每个函数都会返回一个指向下一个状态的函数的指针。可我找不到任何方法来声明这样的函数——感觉我需要一个返回指针的函数,返回的指针指向的又是返回指针的函数……,如此往复,以到无穷。 41 数组大小 42 1.23 能否声明和传入数组大小一致的局部数组,或者由其他参数指定大小的参数数组? 42 1.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 42 声明问题 43 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 43 *1.26 main的正确定义是什么?void main正确吗? 44 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 44 1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 44 1.29 为什么我的编译器不允许我定义大数组,如double array[256][256]? 44 命名空间 44 1.30 如何判断哪些标识符可以使用,哪些被保留了? 44 初始化 47 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 47 1.32 下面的代码为什么不能编译? intf(){char a[]="Hello, world!";} 47 *1.33 下面的初始化有什么问题?编译器提示“invalid initializers ”或其他信息。char *p=malloc(10); 48 1.34 char a[]= "string literal";和char *p="string literal"; 初始化有什么区别?当我向p[i] 赋值的时候,我的程序崩溃了。 48 1.35 char a{[3]}= "abc"; 是否合法? 49 1.36 我总算弄清楚函数指针的声明方法了,但怎样才能初始化呢? 49 1.37 能够初始化联合吗? 49 第2章 结构、联合和枚举 50 结构声明 50 2.1 struct x1{ };和typedef struct{ }x2; 有什么不同? 50 2.2 这样的代码为什么不对?struct x{ }; x thestruct; 51 2.3 结构可以包含指向自己的指针吗? 51 2.4 在C语言中用什么方法实现抽象数据类型**好? 51 *2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 51 2.6 为什么声明extern f(struct x *p); 给我报了一个晦涩难懂的警告信息? 52 2.7 我遇到这样声明结构的代码:struct name {int namelen; char namestr[1];};然后又使用一些内存分配技巧使namestr数组用起来好像有多个元素,namelen记录了元素个数。它是怎样工作的?这样是合法的和可移植的吗? 52 2.8 我听说结构可以赋给变量也可以对函数传入和传出。为什么K&R1;却明确说明不能这样做? 54 2.9 为什么不能用内建的==和!=操作符比较结构? 55 2.10 结构传递和返回是如何实现的? 55 2.11 如何向接受结构参数的函数传入常量值?怎样创建无名的中间的常量结构值? 55 2.12 怎样从/向数据文件读/写结构? 56 结构填充 56 2.13 为什么我的编译器在结构中留下了空洞?这导致空间浪费而且无法与外部数据文件进行“二进制”读写。能否关掉填充,或者控制结构域的对齐方式? 56 2.14 为什么sizeof返回的值大于结构大小的期望值,是不是尾部有填充? 57 2.15 如何确定域在结构中的字节偏移量? 57 2.16 怎样在运行时用名字访问结构中的域? 58 2.17 C语言中有和Pascal的with等价的语句吗? 58 2.18 既然数组名可以用作数组的基地址,为什么对结构不能这样? 58 2.19 程序运行正确,但退出时却“core dump ”(核心转储)了,怎么回事? 58 联合 59 2.20 结构和联合有什么区别? 59 2.21 有办法初始化联合吗? 59 2.22 有没有一种自动方法来跟踪联合的哪个域在使用? 59 枚举 60 2.23 枚举和一组预处理的#define有什么不同? 60 2.24 枚举可移植吗? 60 2.25 有什么显示枚举值符号的容易方法吗? 60 位域 60 2.26 一些结构声明中的这些冒号和数字是什么意思? 60 2.27 为什么人们那么喜欢用显式的掩码和位操作而不直接声明位域? 61 第3章 表达式 62 求值顺序 62 3.1 为什么这样的代码不行?a[i]= i++; 62 3.2 使用我的编译器,下面的代码int i= 7; printf("%d\n", i++ * i++); 打印出49。不管按什么顺序计算,难道不该是56吗? 62 3.3 对于代码int i=3; i=i++; 不同编译器给出不同的i值,有的为3,有的为4,哪个是正确的? 63 *3.4 有这样一个巧妙的表达式:a^= b^= a^= b; 它不需要临时变量就可以交换a和b的值。 63 3.5 可否用显式括号来强制执行我所需要的计算顺序并控制相关的副作用?就算括号不行,操作符优先级是否能够控制计算顺序呢? 64 3.6 可是&&和||操作符呢?我看到过类似while((c = getchar()) != EOF && c != '\n')的代码…… 64 3.7 是否可以安全地认为,一旦&&和||左边的表达式已经决定了整个表达式的结果,则右边的表达式不会被求值? 65 3.8 为什么表达式printf("%d %d", f1(), f2()); 先调用了f2?我觉得逗号表达式应该确保从左到右的求值顺序。 65 3.9 怎样才能理解复杂表达式并避免写出未定义的表达式?“序列点”是什么? 65 3.10 在a[i] = i++;中,如果不关心a[]的哪一个分量会被写入,这段代码就没有问题,i也的确会增加1,对吗? 67 3.11 人们总是说i=i++的行为是未定义的。可我刚刚在一个ANSI编译器上尝试过,其结果正如我所期望的。 67 3.12 我不想学习那些复杂的规则,怎样才能避免这些未定义的求值顺序问题呢? 67 其他的表达式问题 68 *3.13 ++i和i++有什么区别? 68 3.14 如果我不使用表达式的值,那我应该用i++还是++i来做自增呢? 68 3.15 我要检查一个数是不是在另外两个数之间,为什么if(a < b < c)不行? 69 3.16 为什么如下的代码不对?int a=1000, b=1000; long int c=a * b; 69 3.17 为什么下面的代码总是给出0?double degC, degF; degC= 5.0 / 9 * (degF - 32); 69 3.18 需要根据条件把一个复杂的表达式赋给两个变量中的一个。可以用下面这样的代码吗?((condition) ? a : b)= complicated_expression; 70 3.19 我有些代码包含这样的表达式。a ? b=c : d 有些编译器可以接受,有些却不能。为什么? 70 保护规则 71 3.20 “semantics of‘>’change in ANSI C”的警告是什么意思? 71 3.21 “无符号保护”和“值保护”规则的区别在哪里? 71 第4章 指针 74 基本的指针应用 74 4.1 指针到底有什么好处? 74 4.2 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题呢?char *p; *p =malloc(10); 74 4.3 *p++自增p还是p所指向的变量? 75 指针操作 75 4.4 我用指针操作int数组的时候遇到了麻烦。 75 4.5 我有一个char *型指针碰巧指向一些int型变量,我想跳过它们。为什么((int *)p)++; 这样的代码不行? 76 4.6 为什么不能对void *指针进行算术操作? 76 4.7 我有些解析外部结构的代码,但是它却崩溃了,显示出了“unaligned access”(未对齐的访问)的信息。这是什么意思? 76 作为函数参数的指针 76 4.8 我有个函数,它应该接受并初始化一个指针:void f(int *ip){ static int dummy = 5; ip = &dummy;}但是当我如下调用时:int *ip; f(ip); 调用者的指针没有任何变化。 76 4.9 能否用void ** 通用指针作为参数,使函数模拟按引用传递参数? 77 4.10 我有一个函数extern intf(int *); ,它接受指向int型的指针。我怎样用引用方式传入一个常数?调用f(&5);似乎不行。 78 4.11 C语言可以“按引用传参”吗? 79 其他指针问题 79 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 79 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 80 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量中,或者相反? 80 *4.15 我怎样把一个int变量转换为char *型?我试了类型转换,但是不行。 81 第5章 空指针 82 空指针和空指针常量 82 5.1 臭名昭著的空指针到底是什么? 82 5.2 怎样在程序里获得一个空指针? 83 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的内部表达不是0会怎样? 84 NULL 宏 85 5.4 NULL是什么,它是怎么定义的? 85 5.5 在使用非零位模式作为空指针的内部表示的机器上,NULL 是如何定义的? 85 5.6 如果NULL定义成#define NULL((char *)0) ,不就可以向函数传入不加转换的NULL 了吗? 86 5.7 我的编译器提供的头文件中定义的NULL为0L。为什么? 86 5.8 NULL可以合法地用作函数指针吗? 86 5.9 如果NULL和0作为空指针常量是等价的,那我到底该用哪一个呢? 87 5.10 但是如果NULL的值改变了,比如在使用非零内部空指针的机器上,用NULL(而不是0)不是更好吗? 87 5.11 我曾经使用过一个编译器,不使用NULL就不能编译。 87 5.12 我用预处理宏#define Nullptr(type)(type *)0帮助创建正确类型的空指针。 88 回顾 88 5.13 这有点奇怪:NULL可以确保是0,但空(null)指针却不一定? 88 5.14 为什么有那么多关于空指针的疑惑?为什么这些问题如此频繁地出现? 89 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 89 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为0不是更简单吗? 89 5.17 说真的,真有机器用非零空指针吗,或者不同类型用不同的表示? 90 地址0 上到底有什么? 90 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 90 5.19 如何访问位于机器地址0处的中断向量?如果我将指针值设为0,编译器可能会自动将它转换为非零的空指针内部表示。 91 5.20 运行时的“null pointer assignment”错误是什么意思?应该怎样捕捉它? 91 第6章 数组和指针 92 数组和指针的基本关系 92 6.1 我在一个源文件中定义了char a[6],在另一个源文件中声明了extern char *a。为什么不行? 92 6.2 可是我听说char a[]和char *a是等价的。是这样的吗? 92 6.3 那么,在C语言中“指针和数组等价”到底是什么意思? 93 6.4 既然它们这么不同,那为什么作为函数形参的数组和指针声明可以互换呢? 94 数组不能被赋值 95 6.5 为什么不能这样向数组赋值?extern char *getpass(); char str[10]; str=getpass("Enter password:"); 95 6.6 既然不能向数组赋值,那这段代码为什么可以呢?int f(char str[]){ if(str[0] == '\0') str="none";…} 95 6.7 如果你不能给它赋值,那么数组如何能成为左值呢? 95 回顾 96 6.8 现实地讲,数组和指针的区别是什么? 96 6.9 有人跟我讲,数组不过是常指针。这样讲准确吗? 96 6.10 我还是很困惑。到底指针是一种数组,还是数组是一种指针? 96 6.11 我看到一些“搞笑”的代码,包含5["abcdef"]这样的“表达式”。这为什么是合法的C语言表达式呢? 97 数组的指针 97 6.12 既然数组引用会退化为指针,如果array是数组,那么array和&array;又有什么区别呢? 97 6.13 如何声明一个数组的指针? 98 动态数组分配 99 6.14 如何在运行时设定数组的大小?怎样才能避免固定大小的数组? 99 6.15 我如何声明大小和传入的数组一样的局部数组? 99 6.16 如何动态分配多维数组? 100 6.17 有个很好的窍门,如果我这样写:int realarray[10]; int *array = &realarray;[-1]; 我就可以把“array”当作下标从1 开始的数组。 101 函数和多维数组 102 6.18 当我向一个接受指针的指针的函数传入二维数组的时候,编译器报错了。 102 6.19 我怎样编写接受编译时宽度未知的二维数组的函数? 103 6.20 我怎样在函数参数传递时混用静态和动态多维数组? 103 数组的大小 104 6.21 当数组是函数的参数时,为什么sizeof不能正确报告数组的大小? 105 6.22 如何在一个文件中判断声明为extern的数组的大小(例如,数组定义和大小在另一个文件中)?sizeof操作符似乎不行。 105 6.23 sizeof返回的大小是以字节计算的,怎样才能判断数组中有多少个元素呢? 105 第7章 内存分配 106 基本的内存分配问题 106 7.1 为什么这段代码不行?char *answer; printf("Type something:\n"); gets(answer); printf("You typed \"%s\"\n", answer); 106 7.2 我的strcat() 不行。我试了下面的代码:char *s1= "Hello,"; char *s2= "world!"; char *s3= strcat(s1, s2);但是我得到了奇怪的结果。 107 7.3 但是strcat的文档说它接受两个char *型参数。我怎么知道(空间)分配的事情呢? 107 *7.4 我刚才试了这样的代码:char *p; strcpy(p, "abc");它运行正常。怎么回事?为什么它没有出错? 108 *7.5 一个指针变量分配多少内存? 108 7.6 我使用fgets将文件的所有行读入一个数组,为什么读入的每一行都是**后一行的内容呢? 108 7.7 我有个函数,本该返回一个字符串,但当它返回调用者的时候,返回的字符串却是垃圾信息。为什么? 109 *7.8 那么返回字符串或其他聚集的正确方法是什么呢? 110 调用malloc 110 7.9 为什么在调用malloc()时报出了“waring: assignment of pointer from integer lacks a cast”? 110 7.10 为什么有些代码小心翼翼地把malloc返回的值转换为分配的指针类型? 110 *7.11 在调用malloc()的时候,错误“不能把void * 转换为int * ”是什么意思? 111 7.12 我看到下面这样的代码:char *p = malloc(strlen(s) + 1); strcpy(p,s); 难道不应该是malloc ((strlen(s) + 1) * sizeof(char)) 吗? 111 7.13 我为malloc写了一个小小的封装函数。它为什么不行? 111 7.14 我想声明一个指针并向它分配一些内存,但是不行。这样的代码有什么问题?char *p; *p = malloc(10); 111 7.15 我如何动态分配数组? 112 7.16 怎样判断还有多少内存? 112 7.17 malloc(0)是返回空指针还是指向0个字节的指针? 112 7.18 我听说有的操作系统在程序使用的时候才真正分配malloc申请的内存。这合法吗? 112 有关malloc 的问题 112 7.19 为什么malloc返回了离谱的指针值?我的确读过问题7.9,而且也在调用之前包含了extern void *malloc();声明。 112 7.20 我用一行这样的代码分配一个巨大的数组,用于数值运算:double *array = malloc (256 *256 *sizeof(double));malloc()并没有返回空指针,但是程序运行得有些奇怪,好像改写了某些内存,或者malloc()并没有分配我申请的那么多内存。为什么? 113 7.21 我的PC机有8兆内存。为什么我只能分配640K左右的内存? 113 7.22 我的应用程序非常依赖数据结构的节点的动态分配,而malloc/free的代价成了瓶颈。我该怎么做? 113 7.23 我的程序总是崩溃,显然发生在malloc内部的某个地方。但是我看不出哪里有问题。是malloc有bug吗? 113 释放内存 114 7.24 动态分配的内存一旦释放之后就不能再使用,是吧? 114 7.25 为什么在调用free()之后指针没有变空?使用(赋值、比较)释放之后的指针有多么不安全? 115 7.26 当我调用malloc()为一个函数的局部指针分配内存时,我还需要用free()显式地释放吗? 115 7.27 我在分配一些结构,它们包含指向其他动态分配的对象的指针。我在释放结构的时候,还需要释放每一个下级指针吗? 115 7.28 我必须在程序退出之前释放分配的所有内存吗? 115 7.29 我有个程序分配了大量的内存,然后又释放了。但是从操作系统看,内存的占用率却并没有变回去。 116 分配内存块的大小 116 7.30 free()怎么知道有多少字节需要释放? 116 7.31 那么我能否查询malloc包,以查明可分配的**大块是多大? 116 7.32 为什么sizeof不能告诉我它所指的内存块的大小? 116 其他分配函数 117 7.33 (像问题6.14中那样)动态分配数组之后,还能改变它的大小吗? 117 7.34 向realloc()的第一个参数传入空指针合法吗?你为什么要这样做? 118 7.35 calloc()和malloc()有什么区别?应该用哪一个?利用calloc 的零填充功能安全吗?free()可以释放calloc()分配的内存吗,还是需要一个cfree()? 119 7.36 alloca是什么?为什么不提倡使用它? 120 第8章 字符和字符串 121 8.1 为什么strcat(string, '!'); 不行? 121 8.2 我想检查一个字符串是否跟某个值匹配。为什么这样不行?if(string == "value") 121 8.3 如果我可以写char a[] = "Hello, world!"; 那为什么不能写char a[14]; a = "Hello, world!"; 122 8.4 为什么我的strcat 不行?我试了char *s1="Hello,"; char *s2="world!"; char *s3 =strcat(s1, s2);可得到的结果很奇怪。 122 8.5 char a[]= "string literal"; 和char *p= "string literal"; 初始化有什么区别?当我对p[i]赋值的时候,程序崩溃了。 122 8.6 我怎么得到与字符相对应的数字(即ASCII 或其他字符集下的)值?反过来又该怎么做? 123 8.7 C语言有类似其他语言的"substr"(提取子串)这样的函数吗? 123 8.8 我将用户键入的字符串读入数组,然后再显示出来。当用户键入\n这样的序列时,为什么不能正确处理呢? 123 8.9 我注意到sizeof('a')是2而不是1(即不是sizeof(char)),是不是我的编译器有问题? 123 8.10 我正开始考虑多语言字符集的问题。是否有必要担心sizeof(char)会被定义为2,以便表达16位的字符集呢? 124 第9章 布尔表达式和变量 125 9.1 C语言中布尔值该用什么类型?为什么它不是一个标准类型?我应该用#define或enum定义真值和假值吗? 125 9.2 既然在C 语言中所有的非零值都被看作“真”,那是不是把TRUE 定义为1很危险?如果某个内建的函数或关系操作符“返回”不是1的其他值怎么办? 126 9.3 当p是指针时,if(p)是合法的条件表达式吗? 127 9.4 我该使用像TRUE和FALSE这样的符号名称还是直接用1和0来作布尔常量? 127 9.5 我准备使用的一个第三方头文件定义了自己的TRUE和FALSE,它们跟我已经开发的部分不兼容。我该怎么办? 127 第10章 C预处理器 128 宏定义 128 10.1 我想定义一些函数式的宏,例如:#define square(x)x * x但它们并不总是正确的。为什么? 128 10.2 这里有一些的预处理宏,使用它们,我可以写出更像Pascal的C代码。你觉得怎么样? 129 10.3 怎么写一个交换两个值的通用宏? 130 10.4 书写多语句宏的**好方法是什么? 130 10.5 用typdef和预处理宏生成用户定义类型有什么区别? 131 头文件 131 10.6 我第一次把一个程序分成多个源文件,我不知道该把什么放到.c文件,把什么放到.h文件。(“.h”到底是什么意思?) 131 10.7 可以在一个头文件中包含另一头文件吗? 132 10.8 完整的头文件搜索规则是怎样的? 133 10.9 我在文件的第一个声明就遇到奇怪的语法错误,但是看上去没什么问题。 133 10.10 我使用了来自两个不同的第三方库的头文件,它们都定义了相同的宏,如TRUE、FALSE、Min()和Max()等,但是它们的定义相互冲突,而且跟我在自己的头文件中的定义也有冲突。我该怎么办? 133 10.11 我在编译一个程序,看起来我好像缺少需要的一个或多个头文件。谁能发给我一份? 134 条件编译 134 10.12 怎样构造比较字符串的#if预处理表达式? 134 10.13 sizeof操作符可以用在#if预处理指令中吗? 135 10.14 我可以像这样在#define行里使用#ifdef来定义两个不同的东西吗? 135 10.15 对typedef的类型定义有没有类似#ifdef的东西? 135 10.16 我如何用#if表达式来判断机器是高字节在前还是低字节在前? 136 10.17 为什么在我用#ifdef关掉的代码行中报出了奇怪的语法错误? 136 10.18 我拿到了一些代码,里边有太多的#ifdef。我不想使用预处理器把所有的#include 和#ifdef都扩展开,有什么办法只保留一种条件的代码呢? 136 10.19 如何列出所有的预定义宏? 136 奇异的处理 137 10.20 我有些旧代码,试图用这样的宏来构造标识符:#define Paste(a, b) a/**/b 但是现在不行了。为什么? 137 10.21 我有一个旧宏:#define CTRL(c) ('c' & 037)现在不能用了。为什么? 137 10.22 为什么宏#define TRACE(n) printf("TRACE: \%d\n", n) 报出警告“macro replacement within a string literal ”?它似乎把TRACE(count);扩展成了printf("TRACE: \%d\count", count); 138 10.23 如何在宏扩展的字符串字面量中使用宏参数? 138 10.24 我想用ANSI 的“字符串化”预处理操作符#将符号常量的值放入消息中,但它总是对宏名称而不是它的值进行字符串化。这是什么原因? 138 10.25 我想用预处理器做某件事情,但却不知道如何下手。 139 可变参数列表的宏 139 10.26 怎样写可变参数宏?如何用预处理器“关掉”具有可变参数的函数调用? 139 10.27 如何在通用的调试宏中包含__FILE__和__LINE__宏? 140 第11章 ANSI/ISO标准C 142 标准 142 11.1 什么是“ANSI C标准”? 142 11.2 如何得到一份标准的副本? 143 *11.3 我在哪里可以找到标准的更新? 144 函数原型 144 11.4 为什么我的ANSI编译器对用float声明的参数会警告类型不匹配? 144 11.5 能否混用旧式的和新型的函数语法? 145 *11.6 为什么下述声明报出了一个奇怪的警告信息“Struct X declared inside parameter list”? extern int f(struct x *p); 145 11.7 有个问题一直困扰着我,它是由这一行printf ("%d", n); 导致的,因为n是个long int型。难道 ANSI 的函数原型不能检查这种函数的参数不匹配问题吗? 145 11.8 我听说必须在调用printf之前包含。为什么? 146 const 限定词 146 11.9 为什么不能在初始化和数组维度中使用const值?例如const int n = 5; int a[n]; 146 11.10 “const char *p”、“char const *p ”和“char * const p ”有何区别? 146 11.11 为什么不能向接受const char ** 的函数传入char **? 147 11.12 我这样声明:typedef char * charp; const charp p; 为什么是p而不是它所指向的字符为const? 147 main()函数的使用 148 11.13 能否通过将main声明为void来关掉“main没有返回值”的警告? 148 11.14 main()的第3个参数envp是怎么回事? 149 11.15 我觉得把main()声明为void也不会失败,因为我调用了exit()而不是return,况且我的操作系统也忽略了程序的退出/返回状态。 149 *11.16 那么到底会出什么问题?真的有什么系统不支持void main()吗? 149 11.17 为什么以前流行的那些C 语言书总是使用void main()? 149 11.18 在main()中调用exit(status)和返回同样的status真的等价吗? 150 预处理功能 150 11.19 我试图用ANSI“字符串化”预处理操作符'#'向信息中插入符号常量的值,但它字符串化的总是宏的名字而不是它的值。为什么? 150 11.20 警告信息“warning: macro replacement within a string literal”是什么意思? 150 11.21 为什么在我用#ifdef去掉的代码里出现了奇怪的语法错误? 151 11.22 #pragma是什么,有什么用? 151 11.23 “#pragma once”什么意思?我在一些头文件中看到了它。 151 其他的ANSI C 问题 152 11.24 char a[3] = "abc";合法吗?它是什么意思? 152 11.25 既然对数组的引用会退化为指针,那么,如果array是数组,array和&array;之间有什么区别呢? 152 11.26 为什么我不能对void *指针进行算术运算? 152 11.27 memcpy()和memmove() 有什么区别? 153 11.28 malloc(0)有什么用?返回一个空指针还是指向0字节的指针? 153 11.29 为什么ANSI 标准规定了外部标识符的长度和大小写限制? 154 11.30 noalias是怎么回事?在它身上发生了什么? 154 老的或非标准的编译器 154 11.31 为什么我的编译器对**简单的测试程序都报出了一大堆的语法错误?对这段代码的第一行就报错了:main(int argc. char **argv) { return0; } 154 11.32 为什么有些 ASNI/ISO 标准库函数未定义?我明明使用的就是ANSI 编译器。 155 11.33 谁有可以在旧的C 程序和ANSI C 之间相互转换的工具,或者自动生成原型的工具? 156 11.34 为什么声称兼容ANSI 的编译器不能编译这些代码?我知道这些代码是 ANSI 的,因为gcc 可以编译。 156 兼容性 156 11.35 人们好像有些在意实现定义的(implementation-defined)、不确定的(unspecified)和未定义的(undefined) 行为的区别。它们的区别到底在哪里? 157 *11.36 一个程序“合法(legal)”、“有效(valid)”或“符合标准的”(conforming )到底是什么意思? 157 11.37 我很吃惊,ANSI 标准竟然有那么多未定义的东西。标准的唯一任务不就是让这些东西标准化吗? 158 11.38 有人说i=i++的行为是未定义的,但是我刚在一个兼容ANSI 的编译器上测试,得到了我希望的结果。它真的是未定义的吗? 158 第12章 标准输入输出库 159 基本输入输出 159 12.1 这样的代码有什么问题?char c; while((c = getchar()) != EOF) 159 12.2 我有个读取直到EOF的简单程序,但是我如何才能在键盘上输入那个“\EOF”呢?我看 中定义的EOF 是-1,是不是说我该输入-1? 160 12.3 为什么这些代码把**后一行复制了两遍?while(!feof(infp)){fgets(buf, MAXLINE, infp); fputs(buf, outfp);} 160 12.4 我用fgets将文件的每行内容读入指针数组。为什么结果所有的行都是**后一行的内容呢? 161 12.5 我的程序的屏幕提示和中间输出有时没有在屏幕上显示,尤其是当我用管道通过另一个程序输出的时候。为什么? 161 12.6 我怎样才能不等待回车键而一次输入一个字符? 161 printf格式 161 12.7 如何在printf 的格式串中输出一个'%'字符?我试过\%,但是不行。 161 12.8 为什么这么写不对?long int n = 123456; printf("%d\n", n); 162 12.9 有人告诉我不能在printf 中使用%lf。为什么printf() 用%f输出double 型,而scanf 却用%lf 呢? 162 *12.10 对于size_t 那样的类型定义,当我不知道它到底是long 还是其他类型的时候,我应该使用什么样的printf格式呢? 163 12.11 如何用printf 实现可变的域宽度?就是说,我想在运行时确定宽度而不是使用


网友评论