1.如果一个值的类型无法简单地通过观察它的位模式来判断,那么机器是如何知道应该怎样对这个值进行操纵的?
解析:
机器无法做出判断。编译器根据值的声明类型创建适当的指令,机器只是盲目地执行这些指令而已。
2.C为什么没有一种方法来声明字面值指针常量呢?
解析:
因为通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以无法预先知道它的地址。用&操作符得到变量的地址是很容易的,但表达式在程序执行时才会进行求值,此时已经来不及把它的结果作为字面值复制到源代码中。
3.假定一个整数的值是244,为什么机器不会把这个值解释为一个内存地址呢?
解析:
因为通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以无法预先知道它的地址。把244这个值解释为内存地址是编译器的工作。
4.在有些机器上,编译器在内存位置零存储0这个值,对NULL指针进行解引用操作时将访问这个位置。这种方法会产生什么后果呢?
解析:
这是很危险的。首先,解引用一个NULL指针的结果因编译器而异,所以程序不应该这样做。允许程序员在这样的访问之后还能继续运行是很不幸的,因为这时程序很可能没有正确运行。
#include <stdio.h>
#include <stdlib.h>
int main( void ){
int *pi = 0;
printf( "%d\n", *pi );
return EXIT_SUCCESS;
}
输出:
5.表达式(a)和(b)的求值过程有没有区别?如果有的话,区别在哪里?假定变量offset的值为3。
int i[10];
int *p = &i[0];
int offset = 3;
p += offset; (a)
p += 3; (b)
解析:
offset是一个自动变量,存储在运行时堆栈中。3是个字面值常量,存储在静态内存中。
#include <stdio.h>
#include <stdlib.h>
int main( void ){
int i[10];
int *p = &i[0];
int offset = 3;
p += offset;
p += 3;
return EXIT_SUCCESS;
}
6.下面的代码段有没有问题?如果有的话,问题在哪里?
int array[ARRAY_SIZE];
int *pi;
for( pi = &array[0]; pi < &array[ARRAY_SIZE]; ){
*++pi = 0;
}
解析:
有两个错误。对增值后的指针进行解引用时,数组的第一个数组并没有被清零。另外,若指针在越过数组的右边界以后仍然进行解引用,它将把其他某个内存地址的内容清零。 注意,pi在数组之后立即声明。如果编译器恰好把它放在紧跟数组后面的内存位置,结果将是灾难性的。当指针移到数组后面的那个内存位置时,那个最后被清零的内存位置就是保存指针的位置。这个指针(现在变成了零&#