一道被高手指导的菜鸟原创的题目,记录学习第一步。

       自己根据《C陷阱与缺陷》中的一个例子写了这样一个问题问自己大致如下:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i;
    char c;
    for(i = 0; i < 5; i++){
    *(int*)(&c) = ______; //any expressions are ok
    printf("%d\t", i);
    }
    return 0;
}

 
       要求输出0 1 2 3  4,才疏学浅的我仅仅在CodeBlocks的debug下运行成功就认为题目没什么问题了。这个问题本意就是对char型变量的赋值从而修改int型的内存值,因为我读死书认为i和c先后在栈上分配空间,那么c地址与i地址相邻,故一切顺利成章。我沾沾自喜地找到了很多答案,i<<8是其中一个。 

        偶然的机会Coding狂人(编程达人)看到了我的这个问题,一语道破答案是任意合理C语句表达式。开始感觉自己分析的没错,但当我在release下和vc6.0下运行时,结果任意值都能完成输出。经过Coding狂人的指导我明白了编译器的字节对齐,明白了i会在寄存器中自加,c值会被编译器忽略掉,这些是我读死书中不曾学习到的,或者太不认真。最后经过自己的学习将题目修改如下:

#include <stdio.h>

#pragma pack (1)

typedef struct _num
{
    char c;
    int i;
} num;

int main(int argc, char *argv[])
{
    num k = {0,0};
    int i;

    for(i = 0; i < sizeof(k); i++){
        *(int*)&k.c = i*0x100;	//i << 8
        printf("%d\t", k.i);
    }

    return 0;
}
这个问题的答案就被局限了, 用预编译指令指定对齐了宽度,结构体中char型在低字节且只占一个字节,int型地址相对于结构体地址在第二个字节且占四个字节,因此需要把赋值的第二个字节限定为i,高字节限定为0即可。学习之路漫长,自己需要学习的还要很多,给自己加油!


另:在《C语言进阶》书中学到了Linux内核中list.h的一个宏记录如下:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
该宏返回TYPE结构体的MEMBER字段的偏移值,巧妙的用0地址实现了这一效果,其他值也可不过最后需要剪掉该值,不方便。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、下4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值