看完这些问题后,你还会说自己懂 C 语言么?
作者:网络转载 发布时间:[ 2015/10/14 11:54:54 ] 推荐标签:编程语言
5.
int my_strlen(const char *x)
{
int res = 0;
while(*x)
{
res++;
x++;
}
return res;
}
Q: 上面提供的函数应该返回以空终止字符结尾的字符串长度,找出其中存在的一个 bug 。
A: 使用 int 类型来存储对象的大小是错误的,因为无法保证 int 类型能够存下任何对象的大小,应该使用 size_t。
6.
#include <stdio.h>
#include <string.h>
int main()
{
const char *str = "hello";
size_t length = strlen(str);
size_t i;
for(i = length - 1; i >= 0; i--)
{
putchar(str[i]);
}
putchar('n');
return 0;
}
Q: 这个循环是死循环。这是为什么?
A: size_t 是无符号类型。 如果 i 是无符号类型, 那么 i >= 0 永远都是正确的。
7.
#include <stdio.h>
void f(int *i, long *l)
{
printf("1. v=%ldn", *l);
/* (1) */
*i = 11;
/* (2) */
printf("2. v=%ldn", *l);
/* (3) */
}
int main()
{
long a = 10;
f((int *) &a, &a);
printf("3. v=%ldn", a);
return 0;
}
这个程序分别用两个不同的编译器编译并且在一台小字节序的机器上运行。获得了如下两种不同的结果:
1. v=10 2. v=11 3. v=11
1. v=10 2. v=10 3. v=11
Q:你如何解释第二种结果?
A:所给程序存在未定义的行为。程序违反了编译器的强重叠规则(strict aliasing)。虽然 int 在第 (2) 行被改变了,但是编译器可以假设任何的 long 都没有改变。我们不能间接引用那些和其他不兼容类型指针相重名的指针。这是编译器之所以可以传递和在第一行的执行过程中被读取的相同的 long (第(3)行)的原因。
8.
#include <stdio.h>
int main()
{
int array[] = { 0, 1, 2 };
printf("%d %d %dn", 10, (5, array[1, 2]), 10);
}
Q: 这个代码是否是正确的?如果不存在未定义行为,那么它会输出什么?
A: 是的, 这里使用了逗号运算符。首先,逗号左边的参数被计算后丢弃,然后,右边的参数经过计算后被当做整个运算符的值使用,所以输出是 10 2 10。
注意在函数调用中的逗号符号(比如 f(a(), b()))并不是逗号运算符,因此也不会保证运算的顺序,a() 和 b() 会以随机的顺序计算。
9.
unsigned int add(unsigned int a, unsigned int b)
{
return a + b;
}
Q: 函数 add(UINT_MAX, 1) 的结果是什么?
A:对于无符号数的溢出结果是有定义的,结果是 2^(CHAR_BIT * sizeof(unsigned int)) ,所以函数 add 的结果是 0 。
10.
int add(int a, int b)
{
return a + b;
}
Q:函数 add(INT_MAX, 1) 的结果是什么?
A:有符号整数的溢出结果是未定义的行为。
11.
int neg(int a)
{
return -a;
}
Q:这里是否可能出现未定义的行为?如果是的话,是在输入什么参数时发生的?
A:neg(INT_MIN)。如果 ECM 用附加码(补码)表示负整数, 那么 INT_MIN 的值比 INT_MAX 的值大一。在这种情况下,-INT_MIN 造成了有符号整数的溢出,这是一种未定义的行为。
12.
int div(int a, int b)
{
assert(b != 0);
return a / b;
}
Q:这里是否可能出现未定义的行为?如果是的话,是在什么参数上发生的?
A:如果 ECM 用附加码表示负数, 那么 div(INT_MIN, -1) 导致了与上一个例子相同的问题。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南