栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C和指针 第6章 指针 6.17 问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C和指针 第6章 指针 6.17 问题

1.如果一个值的类型无法简单地通过观察它的位模式来判断,那么机器是如何知道应该怎样对这个值进行操纵的? 

解析:
机器无法做出判断。编译器根据值的声明类型创建适当的指令,机器只是盲目地执行这些指令而已。

2.C为什么没有一种方法来声明字面值指针常量呢? 
解析:
因为通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以无法预先知道它的地址。用&操作符得到变量的地址是很容易的,但表达式在程序执行时才会进行求值,此时已经来不及把它的结果作为字面值复制到源代码中。 

3.假定一个整数的值是244,为什么机器不会把这个值解释为一个内存地址呢? 
解析:
因为通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以无法预先知道它的地址。把244这个值解释为内存地址是编译器的工作。 

4.在有些机器上,编译器在内存位置零存储0这个值,对NULL指针进行解引用操作时将访问这个位置。这种方法会产生什么后果呢? 
解析:
这是很危险的。首先,解引用一个NULL指针的结果因编译器而异,所以程序不应该这样做。允许程序员在这样的访问之后还能继续运行是很不幸的,因为这时程序很可能没有正确运行。  
#include
#include

int main( void ){
    int *pi = 0;
    
    printf( "%dn", *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)
#include
#include

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在数组之后  立即声明。如果编译器恰好把它放在紧跟数组后面的内存位置,结果将是灾难性的。当指针移到数组后面的那个内存位置时,那个最后被清零的内存位置就是保存指针的位置。这个指针(现在变成了零)因为仍然小于&array[ARRAY_SIZE],所以循环将继续执行。指针在它被解引用之前增值,所以下一个被破坏的值就是存储于内存位置4的变量(假定整数的长度为4字节)。如果硬件并没有捕捉到这个错误并终止程序,这个循环将一直继续下去,指针在内存中继续前行,破坏它遇见的所有值。当再一次到达这个数组的位置时,它就会重复上面这个过程,从而导致一个微妙的无限循环。 
*/

#include
#include

#define ARRAY_SIZE 5 

int main( void ){
    int array[ARRAY_SIZE];
    int *pi;
    
    printf( "pi = %p, &array[0] = %p, &array[%d] = %p.n", pi, &array[0], ARRAY_SIZE, &array[ARRAY_SIZE] );
    for( pi = &array[0]; pi < &array[ARRAY_SIZE]; ){
        *++pi = 0;
    } 
    
    printf( "print the elements in array by using pointer points to the array:n" );
    for( pi = &array[0]; pi < &array[ARRAY_SIZE]; ){
        printf( "%d ", *pi++ );
    }
    printf( "n" );
    printf( "pi = %pn", pi );
    
    return EXIT_SUCCESS;
}

7.下面显示了几个内存位置的内容。每个位置由它的地址和存储于该位置的变量名标识。所有数字以十进制形式表示。使用这些值,用4种方法分别计算下面各个表达式的值。首先,假定所有变量都是整型,找到表达式右值,再找到它的左值,给出他所指定的内存位置的地址。接着,假定所有变量都是指向整型的指针,重复上述步骤。注意:在执行地址运算时,假定整形和指针的长度都是4字节。 
变量    地址    内容    变量    地址    内容
a        1040    1028    o        1096    1024
c        1056    1076    q        1084    1072
d        1008    1016    r         1068    1048
e        1032    1088    s        1004     2000
f         1052    1044    t         1060    1012
g        1000    1064    u        1036    1092
h        1080    1020    v        1092    1036
i         1020    1080    w        1012    1060
j         1064    1000    x         1072    1080
k        1044    1052    y         1048    1068
m       1016    1008    z         2000    1000
n        1076    1056                 

#include
#include

#define byte_of_int 4
#define byte_of_pointer 4
typedef int * int_ptr;
typedef int int_alias;

int main( void ){
    return EXIT_SUCCESS;
}
 
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/977155.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号