user-0 提问: 大家来看看 谭浩强 的代码有没有问题

回复:
user: user-1
content: 看了这么久，我想问谁是谭浩强？

user: user-2
content: 引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，......  我敢肯定，我的C语言课本不是谭浩强的， 我是这两年才听说这个人的

user: user-3
content: 403 Forbidden

user: user-4
content: 引用 32 楼 bear234 的回复:while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break; ok   看来确实是书错了   [/quote] 你认识 if else 却不认识 do while ...... 我和鼠侠的例子 其实是没什么区别的

user: user-4
content: 引用 31 楼 bear234 的回复:1) 二元运算符 和 一元运算符    是在“算术运算符”的概念里的。换句话说，如果说某个运算符是一元还是二元，那么它一定是算数运算符，而不是关系运算符，也不是赋值运算符。 2）先声明了就能使用了？声明了，只是编译器认识了而已，并不一定就能使用。这里是在谈使用，不是在区分声明和定义的区别。至于你的例子，只能说你在玩文字游戏了，“先定义”中的“先”，是告诉你你在使用时，要保证其已经被定义过。而不是代码行上的先后顺序。 3）while语句和do while语句都分不清，你在逗我吗？  至于变长数组   我回复了  确实是书写错了  你弄错了 一元二元三元 说的只是 这个运算符 和 多少个操作数结合 比如说 一元运算符  -  他只会和1个操作数结合 -a  全部意思仅此而已 请不要随意加什么算术运算符这样的限制  再举一个例子整个C语言中唯一一个 三元运算符 ?: 三元的意思也仅仅是说 整个运算符有三个操作数  而且 这个运算符 也不是你所谓的算术运算符 对吧  再贴一张图   你看这张图里面 标记二元运算符的还有  > 大于 < 小于 >= 大于等于 <= 小于等于 并不是你所说的 只有"算术运算符" 才有一元二元的

user: user-5
content: 实践是检验真理的唯一标准

user: user-6
content: 引用 20 楼 lin5161678 的回复:[quote=引用 15 楼 bear234 的回复:] 有不能和赋值运算符组合成复合运算符的二元运算符？ && 运算符是不是二元运算符  || 运算符是不是二元运算符  += 运算符是不是二元运算符 (不错 这个说法已经造成递归 错得离谱) 引用 15 楼 bear234 的回复:先定义，后使用 ----- 定义是对声明的实现或者实例化。连接器(linker)需要它（定义）来引用内存实体。所以定义只能有一次。 所以这句话有什么问题？ 这句话的问题是 正确的说法应该是 先声明再使用 void foo() { 	extern int x; 	printf("%d", x);//这里已经可以使用 x 但是x并没有定义  } int x = 99;//x直到这里才定义  别告诉我 你不清楚声明和定义的区别 引用 15 楼 bear234 的回复:C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ 你怎么理解这句话和这句话对不对毫无关系  这句话说 实型常量都是双精度  但是 存在一个这样的实型常量1.23f 并不是不是double 而是float 那么这句话毫无疑问是错的  引用 15 楼 bear234 的回复:循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错 	while(1) 		do 			x = 99;//第一个分号到了 问题是 这个循环体是在第二个分号才结束   		while(0);   如此漏洞百出的描述 你都看不出哪里错  只能说明 谭C误导得挺成功的 引用 15 楼 bear234 的回复:int a[n]: C99 允许变长数组  之前的标准不允许   这里有什么问题？ 有什么问题我已经在前面说明过了 但是你好像选择性失明 现在我加大加粗标红 请看清楚 不要再问出别人早就回答过的问题  问题就是 谭C第四版号称支持C99 问题就是谭C第四版讲解的是就是C99   排版错了 重新发一次 上一楼作废 抱歉[/quote]   好吧  我并没有什么主观意思  谭浩强的书我没看过    我只是想知道为什么大家总说他错误很多.....

user: user-6
content: 引用 22 楼 sholber 的回复:[quote=引用 15 楼 bear234 的回复:] [quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错  [/quote] 最近不常来CSDN，既然今天赶上了，也来说两句，单说这个while语句。 我没看过谭书，不知道你这段话是自己穿靴戴帽加上的，还是谭果真是这么写的。但无论如何，都是错的。请看： while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break;[/quote]   ok   看来确实是书错了

user: user-6
content: 引用 18 楼 lin5161678 的回复:[quote=引用 15 楼 bear234 的回复:] 有不能和赋值运算符组合成复合运算符的二元运算符？ && 运算符是不是二元运算符  || 运算符是不是二元运算符  += 运算符是不是二元运算符 (不错 这个说法已经造成递归 错得离谱) 引用 15 楼 bear234 的回复:先定义，后使用 ----- 定义是对声明的实现或者实例化。连接器(linker)需要它（定义）来引用内存实体。所以定义只能有一次。 所以这句话有什么问题？ 这句话的问题是 正确的说法应该是 先声明再使用 void foo() { 	extern int x; 	printf("%d", x);//这里已经可以使用 x 但是x并没有定义  } int x = 99;//x直到这里才定义  别告诉我 你不清楚声明和定义的区别 引用 15 楼 bear234 的回复:C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ [/code] 你怎么理解这句话和这句话对不对毫无关系  这句话说 实型常量都是双精度  但是 存在一个这样的实型常量1.23f 并不是不是double 而是float 那么这句话毫无疑问是错的  [quote=引用 15 楼 bear234 的回复:] 循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错 	while(1) 		do 			x = 99;//第一个分号到了 问题是 这个循环体是在第二个分号才结束   		while(0);   如此漏洞百出的描述 你都看不出哪里错  只能说明 谭C误导得挺成功的 引用 15 楼 bear234 的回复:int a[n]: C99 允许变长数组  之前的标准不允许   这里有什么问题？ 有什么问题我已经在前面说明过了 但是你好像选择性失明 现在我加大加粗标红 请看清楚 不要再问出别人早就回答过的问题 显得自己笨 问题就是 谭C第四版号称支持C99 问题就是谭C第四版讲解的是就是C99 [/quote]   1) 二元运算符 和 一元运算符    是在“算术运算符”的概念里的。换句话说，如果说某个运算符是一元还是二元，那么它一定是算数运算符，而不是关系运算符，也不是赋值运算符。 2）先声明了就能使用了？声明了，只是编译器认识了而已，并不一定就能使用。这里是在谈使用，不是在区分声明和定义的区别。至于你的例子，只能说你在玩文字游戏了，“先定义”中的“先”，是告诉你你在使用时，要保证其已经被定义过。而不是代码行上的先后顺序。 3）while语句和do while语句都分不清，你在逗我吗？  至于变长数组   我回复了  确实是书写错了

user: user-7
content: &&= 和  ||= 曾经也是可以的，现在的编译器 和 标准没看过，不清楚可以不

user: user-8
content: 引用 2 楼 K8001 的回复:[quote=引用 1 楼 fly_dragon_fly 的回复:] 有兴趣讨论可以贴下代码, 图片就不想看了  上面有谭的文字,这样对代码的作者有一点证明力  我不贴代码是想大家用自己对C的理解去审视这段代码,而不是复制下来一运行说是对是错. [/quote]代码不长,看了一下, 老谭的代码应该在TC下用的,可能当时没什么问题(记不清了), 其实差一个const, 反正我记得第一次使用const是在c++而不是c, 版本b应该是const char *a="", 这样就很清楚,a内容不可改变, 对const的内容改变, 标准应该是未定义吧

user: user-9
content: 引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。  什么是不可预测的问题，使用VLA为什么会带来不可预测的问题？说来我听听。

user: user-9
content: 引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 看了@lin5161678 指出的对@bear234 朋友评论的反驳，实在看不下去，以下稍作见解。 1、&&和|| 属于逻辑运算符，本来就不是用来计算，而是用来控制，因其恰好在C中可以产生1或0的结果，而在此讨论“与赋值运算符结合”的问题，本身就有问题。可见这位朋友对“运算”的理解。 2、“先定义，后使用”，这句话在编译器层面上，我认同@bear234 朋友的意见，声明给别人使用，定义以供链接；至于先定义后使用从代码角度上来说，由于未知这句话所出的上下文，暂不做猜测。至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 3、“C的实数常量都是双精度型”，竟然说出了“存在一个这样的实型常量1.23f” 这样的话，1.23f只不过告诉编译器，用float来理解这个变量。如果按照lin5161678的说法，那（1.23+5.67f）岂不是也是一个“实型常量”？ 4、“while语句的范围只到while后面第一个分号处”，这里的“第一个分号”表达的是“第一个语句”的意思；另外，不管加不加大括号，do while都已经是一个复合语句，lin5161678 脱离语言，从文字上挑毛病，实在不该。这里我在给你举一个例子：  while(1)     printf(";;;;;;;");  //哇，好多分号！  5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。  233 看得出来，你应该是学谭浩强的书掌握了C。 顺便说一下，翻遍C标准，也不见“运算”的定义，那你认为什么是运算呢？运算仅仅是加减乘除左移右移？不敢苟同。

user: user-4
content: 引用 24 楼 cjqpker 的回复:至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 这里你好像分不清 编译期 和 运行期  按照你的说法 哪怕 int x = 99; 写在这个位置 也是先定义  那么我另外再举一个例子好了  #include <stdbool.h>  int main() { 	printf("%d\n", x); 	return 0; } int x = 99;  x "先定义"了 但是这段代码无法通过编译   我说清楚了吗  假如 谭C的说法是正确的 那么第一段代码中的变量x 是有先定义 那么第二段代码中的变量x 一样是有先定义 但是 第一段代码是正常的 第二段代码却是错误的 于是 谭C的说法是错误的

user: user-9
content: 以上发个代码，证明朕来过了。嘎嘎~~

user: user-9
content: # include <stdio.h>  struct t {char c; float f;} f (struct t t) {     printf ("%c,%f", t.c, t.f);     return t; }  int main (void) {     f ((struct t) {'x', 0.01}); }

user: user-4
content: 引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 看了@lin5161678 指出的对@bear234 朋友评论的反驳，实在看不下去，以下稍作见解。 1、&&和|| 属于逻辑运算符，本来就不是用来计算，而是用来控制，因其恰好在C中可以产生1或0的结果，而在此讨论“与赋值运算符结合”的问题，本身就有问题。可见这位朋友对“运算”的理解。 2、“先定义，后使用”，这句话在编译器层面上，我认同@bear234 朋友的意见，声明给别人使用，定义以供链接；至于先定义后使用从代码角度上来说，由于未知这句话所出的上下文，暂不做猜测。至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 3、“C的实数常量都是双精度型”，竟然说出了“存在一个这样的实型常量1.23f” 这样的话，1.23f只不过告诉编译器，用float来理解这个变量。如果按照lin5161678的说法，那（1.23+5.67f）岂不是也是一个“实型常量”？ 4、“while语句的范围只到while后面第一个分号处”，这里的“第一个分号”表达的是“第一个语句”的意思；另外，不管加不加大括号，do while都已经是一个复合语句，lin5161678 脱离语言，从文字上挑毛病，实在不该。这里我在给你举一个例子：  while(1)     printf(";;;;;;;");  //哇，好多分号！  5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。 他做了什么贡献和他的书是不是写错了 毫无关系  我没有一个字是在评价关于谭浩强做出了什么贡献  请看清楚 我只描述 谭C的书中出现的错误之处 请问 是不是因为他有贡献 所以我们不可以说他写错了? 你对运算的理解太过于片面 为了照顾你的理解  我这样说吧 += 这个运算符就是你所谓的用来计算的 += 这个运算符是二元运算符  但是 并不能和 =符号组合成为 +== ? 所以谭C这个断言是错误的   你好像连什么是实数常量都不懂  按照C语言标准文档的描述  12.3f 这个完全符合实数常量的语法定义  请不要信口开河 对于不了解的东西 不要不懂装懂  既然是第一个语句的意思 为什么不老老实实的说清楚是第一个语句 为什么要使用 "第一个分号" 这种漏洞百出的说法 既然使用了漏洞百出的说法 被我看出漏洞 怪我咯? do while 并不是复合语句 复合语句说的是 {} 我发现你对C的理解极其片面 有许多都是基于自己的想象  这很不好 请多看一些靠谱的书 和 文档 比如 C99标准文档(你喜欢看C89标准文档也行)  最后的关于 VLA的问题 是的 请大声的说  请! 不! 要! 使! 用! 不! 准! 使! 用! 这种有用的建议请千万不要吝啬 请多多的告诉新手  但是 不好用的特性不能说成是错误的语法 书既然是在介绍C99  那么就应该按照C99的说法说清楚  这个做法是合乎语法的 但是由于原因123 建议不要使用 我说清楚了吗  我说的是 你的合理建议并不能为谭C的错误洗地 谭C说VLA是错的 这句话是的的确确是错的 毋庸置疑

user: user-10
content: 谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 看了@lin5161678 指出的对@bear234 朋友评论的反驳，实在看不下去，以下稍作见解。 1、&&和|| 属于逻辑运算符，本来就不是用来计算，而是用来控制，因其恰好在C中可以产生1或0的结果，而在此讨论“与赋值运算符结合”的问题，本身就有问题。可见这位朋友对“运算”的理解。 2、“先定义，后使用”，这句话在编译器层面上，我认同@bear234 朋友的意见，声明给别人使用，定义以供链接；至于先定义后使用从代码角度上来说，由于未知这句话所出的上下文，暂不做猜测。至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 3、“C的实数常量都是双精度型”，竟然说出了“存在一个这样的实型常量1.23f” 这样的话，1.23f只不过告诉编译器，用float来理解这个变量。如果按照lin5161678的说法，那（1.23+5.67f）岂不是也是一个“实型常量”？ 4、“while语句的范围只到while后面第一个分号处”，这里的“第一个分号”表达的是“第一个语句”的意思；另外，不管加不加大括号，do while都已经是一个复合语句，lin5161678 脱离语言，从文字上挑毛病，实在不该。这里我在给你举一个例子：  while(1)     printf(";;;;;;;");  //哇，好多分号！  5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。

user: user-9
content: 引用 15 楼 bear234 的回复:[quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ [/quote]  我们不用“实数常量”这个术语，但如果你要用，我们不反对，但我们有一个问题：C中的实数包括整数类型和实浮点类型，难不成整型常量也是双精度型 ？

user: user-9
content: 引用 15 楼 bear234 的回复:[quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错  [/quote] 最近不常来CSDN，既然今天赶上了，也来说两句，单说这个while语句。 我没看过谭书，不知道你这段话是自己穿靴戴帽加上的，还是谭果真是这么写的。但无论如何，都是错的。请看： while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break;