由于我已经编码 C 20 多年了,我认为是时候参加考试了!看看我是否学到了任何东西,或者我是否只是一些欺诈行为,向互联网上的初学者发布免费但不正确的建议。
这个站点(我没有附属)提供免费的 C 测试。https://www.tutorialspoint.com/cprogramming/cprogramming_mock_test.htm。
我参加了测试 1,但以 50 分中的 34 分惨败!是这个吗?我必须放弃我的 C 程序员职业吗?这个 Tutorialspoint 站点及其测试有多好?
具体来说,我未能用测试预期的答案回答 Q7、Q9、Q10、Q14、Q16、Q17、Q19、Q21、Q27、Q28、Q31、Q32、Q33、Q35、Q38、Q46。这些问题的正确答案是什么?
此外,当我在我的符合实现 C 编译器 ( gcc -std=c11 -pedantic-errors)上编译问题时,它们甚至都不会通过编译。这是为什么?我和/或我的编译器坏了吗?或者这个网站根本不是很好?
Lun*_*din 14
这个网站一点都不好。
这些问题是为 1999 年撤回的旧版本 C 语言编写的。它允许您将 main 编写为main()没有返回类型。这已经超过 20 年的 C 无效,所以这就是它不能编译的原因。您需要使用-std=c90.
尽管在带有隐式 int before 的旧 C90 中main(),操作系统将使用函数 main() 的返回值,因此如果这些示例中没有 return 语句,这意味着未定义的行为 (C11 6.9.1/12)。
值得注意的是,整个测试也缺少\nin printf,这意味着stdout在程序结束之前不会刷新。C 保证它在程序终止时被刷新。
具体来说,这些问题也是不正确的:
Q7:没有一个答案可能是正确的。操作数'A'和255是 类型int,因此加法(假设 A=65)保证不会溢出,而是导致 65 + 255 = 320。int然后通过简单的赋值将这个结果转换为类型c为char。这又可能是有符号或无符号类型,具体取决于编译器。这会影响转换是按照 C11 6.3.1.3/2 进行明确定义还是按照 6.3.1.3/3 进行实现定义。一种可能的结果是 320 = 140h,被截断:40h = 64。这会'@'在 Linux 的 gcc x86 编译器上打印字符。
Q9:代码导致编译器错误,因为它违反了简单赋值规则(引用)的约束。他们可能打算unsigned x = 5, *y=&x, *p = y+0;在这种情况下编写结果未指定 - 不能保证表达式*y=&x在表达式之前计算*p = y+0。参见 C11 6.7.9/23:
初始化列表表达式的计算相对于彼此是不确定的,因此任何副作用发生的顺序是不确定的。
所以无论你怎么说,整个问题从根本上都是错误的。
Q10:关于是否对malloc. 但除此之外,假设#include <stdlib.h>存在,代码就可以了。如果包含不存在(如问题中所示),则代码已损坏并且任何事情都可能发生。
Q14:这是一个无限循环,无限打印“Hello”。它不打印“无限循环”。
问题 16:参见问题 14。此外,一个体面的编译器(例如gcc -Wall)可能会在此处抛出一些诊断消息,因此回答“编译错误”不一定是错误的。取决于编译器设置。
Q17:假设计算机是 2 的补码,那么 -2。从理论上讲,它可以打印 -1 或 -2 或 -(大数),具体取决于计算机是使用补码、补码还是有符号幅度。
Q19:正确答案是编译器错误。再次因为简单分配的限制。
Q21:假设65是 的符号表值'A',那么它可以打印'A'(little endian)或对应于0(big endian)的符号。后者很可能看起来像“垃圾”。
Q27: 正确答案是无效使用 strcmp 函数,因为#include <string.h>缺少。否则它会打印 0。
Q28:编译错误。有趣的是,测试是不一致的。在这里它突然不允许从整数到指针的隐式转换,它早先愉快地(并且错误地)允许的。
Q31:B 或 C 甚至 D。这取决于 int 的大小,几乎可以肯定是 2 或 4。但是,编译器可以自由地在联合的末尾添加填充,因此它不妨打印一个更大的数字。
问题 32:正确答案确实依赖于编译器,但是...为什么哦,为什么它在问题 31 中不依赖于编译器呢?
Q33:C 允许我们编写short,short int或int short- 所有等价物,所以这个问题没有多大意义。
Q35:没有输出,因为代码没有编译。
Q38:输出是 7,而不是 6。
Q46:仅分配了联合的 char 成员,其余部分包含不确定值。联合成员 x 被声明为具有自动存储持续时间并且从不获取其地址,因此访问它是未定义的行为。/sf/answers/2847242191/
如果不是这样,它会尝试打印一些不确定的值(“垃圾”),甚至是 65 或 0,具体取决于 CPU 字节序。
我对TutorialsPoint 的C 模拟测试 #1 中显示的代码持许多保留意见。使用对 C99 无效的代码,更不用说 C11 或 C17,是很奇怪的。上一千年的代码不应该仍然被教授给新程序员——除非作为语言自首次标准化以来如何变化的对象课程。
这个 SO 问题最初讨论了模拟测试的 Q3,但 SO 问题和主要答案已被修改以删除对该问题的评论。
Q3的代码是:
#include<stdio.h>
main()
{
char s[]="hello", t[]="hello";
if(s==t){
printf("eqaul strings");
}
}
Run Code Online (Sandbox Code Playgroud)
数组s和t必须位于不同的位置;它们是单独的数组,由相同的字符串初始化,但仍然是单独的数组,因此存储在不同的地址。条件比较数组存储的地址(字符串比较将使用strcmp()或等效),并且数组存储在不同的地址,因此比较结果为假。
对字符串文字的 SO 以及它们可以存储在同一位置的事实进行了一些讨论。然而,这种讨论被误导了。它不适用于此代码。用于初始化数组的字符串可以共置,但数组本身不能共置。但是,假设定义是指针,而不是数组:
char *s = "hello", *t = "hello";
Run Code Online (Sandbox Code Playgroud)
现在很可能s和t包含相同的地址,尽管它们也可能包含不同的地址。(的地址s和t必须是不同的;它们是两个独立的指针变量)。
但是问题中代码中的数组初始值设定项必须初始化两个单独的数组,并且这些单独的数组必须存储在单独的地址中,因此问题中的比较s == t必须为假,因此不会打印任何内容。