文章随机晒最新文章关照最多的

jiayi Rss

struct 之 地址寻址与地址转换

| Posted in C/C++ |

7

考完最后一科,嘎嘎,终于考完了~这个学期再也不敢懈怠考试了,抓了一段功课,有些效果。。恩,博客恢复更新~
说说C语言的 struct 吧。虽然基本,但有些东西还是挺有意思的。先看看 struct 的地址有哪些有意思的东西吧~

下面有一段代码,其中先给出一个 _student 结构体,声明后付初值。用 struct 的”点(.)”操作符打印其中 name 对象的地址与字符串。然后通过类似 struct 0 地址寻址的方式打,这里给了四句话,其中一句用“毒瘤”注释,说明不可取…最后我们在struct 寻址的基础上截取打印 name 字符串,唔,这里有两句“毒瘤”。 

C code

#include<stdio.h>
int main()
{
    struct _student {
        int sex;
        char *name;
    } student;

    student.name="T-MAC";
    student.sex=1;
    struct _student haha=student;

    /* 一般打印 */
    printf("%p ",&student.name);
    printf("%s ",*(&student.name));

    /* struct寻址打印 */
    printf("正常加倍寻址:%p ",&student+sizeof(int));
    printf("强制算数寻址:%p ",(char *)&student+sizeof(int));
    //printf("毒瘤 %s ",*((char *)&student+sizeof(int))); /* 毒瘤 */
    printf("麦神%s ",*(struct _student *)((char *)&student+sizeof(int)));

#define NAME_ADDR  (struct _student *)((char *)&student+sizeof(int))

    /* struct寻址 + 偏移量 打印 */
    //printf("毒瘤 %s ",*NAME_ADDR+2); /* 毒瘤 */
    //printf("毒瘤 %s ",(char *)*NAME_ADDR+2); /* 毒瘤 */
    printf("麦神%s ",(char *)*((int *)NAME_ADDR)+2);
}

正常加倍寻址和强制算数寻址不难理解,只是在用此方法时稍微留下神。

第一句“毒瘤” 编译可以通过,但运行时报“断错误”。(char *)&student+sizeof(int)) 计算的地址是一个 char * 型,看来用它引用 struct 成员 是不可取的。
而其后的“麦神”语句通过将 (char *)&student+sizeof(int)) 转换成 struct _student * 的到了正确结果。

最后我们要对 “T-MAC” 使用偏移量方法进行截取打印。这里的第一个“毒瘤”语句也许是我们首先想到的,但编译失败。* NAME_ADDR 看似是对struct 成员 的引用,但实质是一个 struct 对象对 struct 对象 进行加法操作,显然是不允许的!
好吧,既然 struct 对象 进行偏移量的加法不可行,那我们强制将其转换为 char * 怎么样呢…额,第二醒目的“毒瘤”告诉我们不行。。原因如下:结构类型(包括 union)不是数量类型(Scalar Type)。只有在数量类型之间才能进行转换。数量类型包括算术类型和指针类型,算术类型由包括整数类型和浮点类型。哦,原来是类型不匹配。
既然两条路都不通,难道就实现不了吗…我们还有笨法,即最后一句“麦神”。从源头将那块地址转换为一个 int * 型,因为 指针 实际是一个整型数。如果大家觉得 intchar * 对应不够明确,将 (int *)NAME_ADDR 换成 (char **)NAME_ADDR 也是没问题的。

struct 结构体其他有趣的东西要等回家写咯~明一早走。Bless all of you. Bless myself ~

Comments (7)

我也考完啦 同乐 呵呵

嘿嘿,捅了捅了

好博啊,学到不少东西!

过奖了…互相学习咯~

博主您好,申请贵站的友情连接,贵站连接已经做好
希望能通过!
我的博客是www.hhz80.cn/博客名称是 红孩子

加上了~

怎么联系你打广告啊,帅哥

Write a comment

You must be logged in to post a comment.