C语言 结构体中的成员域偏移量

//C语言中结构体中的成员域偏移量
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct _student{
    char name[30];//32
    int num;
}Student;

void main(){
    Student *p = NULL;
    printf("%x\n", p);//打印 0
    p = p - 1;
    printf("%x\n",p);//打印ffffdc
    //说明 指针的加法运算前面已有详述,p - 1移动了 sizeof(Student)个字节
    //由于结构体字节对齐原则,char name[30]数组占据32个字节,不是30个,不明白请看结构体那一章
    //计算出p的步长是 32+4=36

    p = p - 2;
    printf("%x\n", p);//打印ffff94

    p = p + 2;
    printf("%x\n", p);//打印ffffdc
    //说明:以上两个的解释同p-1

    p = (Student *)1;
    p = p - 1;
    printf("p - 1=%x\n", p);//打印ffffdd
    p = (Student *)1;
    p = p - p;
    //警告:警告    1    warning C4047: “=”:“Student *”与“int”的间接级别不同  tec01.c    33    1    C005
    //警告产生原因是p-p得出的值是int型 p是Student *类型
    //由此说明:p - p和p-1有所区别,p-p只是单纯的p的值加减,p-p=0,返回值是int型,而p-1是指针间的运算,返回值是指针
    printf("p - p=%x\n", p);//打印0

    //结构体指针中 . ->操作符本质上是寻址,寻找每一个成员相对于结构体起始位置的内存偏移,
    //该操作在cpu里执行,不会操作内存,所以 p->num等价于  ((Student *)0)->num  因为不会操作内存,所以不会报错
    printf("%x\n", &(p->num));//打印20   (此处是16进制)
    //说明 &(p->num)是取p->num得地址   num相对于结构体起始位置的内存偏移量是char name[30]  32个字节(结构体字节对齐原则)
    system("pause");
}

时间: 2024-08-27 00:29:23

C语言 结构体中的成员域偏移量的相关文章

在C语言结构体中添加成员函数

我们在使用C语言的结构体时,经常都是只定义几个成员变量,而学过面向对象的人应该知道,我们定义类时,不只是定义了成员变量,还定义了成员方法,而类的结构和结构体非常的相似,所以,为什么不想想如何在C语言结构体中添加成员变量呢 在C语言的结构体中是不能直接定义成员函数的,这点和C++不同,但是我们可以通过定义一个函数指针的方式来指向一个方法. 示例代码如下: 1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct node 4

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

c语言结构体中动态数组的使用

[背景] c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间. [正文] 1. 动态数组在结构体中间 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int a; char buf[0]; // 或者char buf[]; int b; }Node; int main() { printf("%d\n", si

如何知道结构体中某个成员相对结构体开始的偏移

#include <stdio.h>#define STRUCT_OFFSET(stru_name, element) (unsigned long)&((struct stru_name*)0)->elementstruct stru_addr{    int a;    char b;    int d;    char c; }; int main(void){    struct stru_addr s;    printf("start addr of s =

结构体中string成员的问题

在结构体中定义字符串的成员的时候要注意定义成string有时候,在某些程序中给成员赋值会崩溃,但是不确定到底什么情况会崩溃.运行报错如下: Program received signal SIGSEGV, Segmentation fault. 0xb665489c in std::string::assign(char const*, unsigned int) () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 typedef struct

C语言结构体中的函数指针

这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in-c-struct.html,转载请注明源地址. 引言 指针是C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序.我们要记住指针是一个指向内存地址的变量.指针可以引用如int.char……常见的数据类型,例如: int * intptr; // 声明一个指向整型值的

libev 中 ev_loop 结构体中的成员变量

1.ev_loop是libev用来描述事件循环的结构体.在libev中的定义比较绕,这里把它摘抄出来,做下注释,方便学习.libev的定义如下 struct ev_loop { ev_tstamp ev_rt_now; #define ev_rt_now ((loop)->ev_rt_now) #define VAR(name,decl) decl; #include "ev_vars.h" #undef VAR }; #include "ev_wrap.h"

C语言结构体里的成员数组和指针

struct test{ int i; char *p; }; struct test *str; int a = 1; char *b = "ioiodddddddddddd"; str = (struct test *)malloc(sizeof(struct test));//结构体指针不为null str->i = a; str->p = b; printf("%s\n",str->p); //输出ioiodddddddddddd retu

程序设计基石与实践系列之失落的C语言结构体封装艺术

英文来源于 Eric S. Raymond-- The Lost Art of C Structure Packing 谁该阅读这篇文章 本文是关于削减C语言程序内存占用空间的一项技术--为了减小内存大小而手工重新封装C结构体声明.你需要C语言的基本知识来读懂本文. 如果你要为内存有限制的嵌入式系统.或者操作系统内核写代码,那么你需要懂这项技术.如果你在处理极大的应用程序数据集,以至于你的程序常常达到内存的界限时,这项技术是有帮助的.在任何你真的真的需要关注将高速缓存行未命中降到最低的应用程序里