关于结构体地址与结构体指针的一些分析

 当我在学习C语言的链表实现时,遇到了一些问题,通常链表的表头是通过结构体创建的,而表头中包含所需要指向的第一个节点与整个链表长度等信息,对于在表头中所存储的地址信息感到一点疑惑。
如一下创建的一个单向链表:

typedef struct _tag_LinkListNode LinkListNode;       //结点取别名

struct _tag_LinkListNode
{
    LinkListNode* next;
};       // 结点指针域定义      

typedef struct _tag_LinkList
{
    LinkListNode header;
    int length;
} TLinkList;        //头结点定义

struct Value
{
    LinkListNode header;
    int v;
};           //数据域定义

此时有如下问题:
1.TLinkList中的header存储的是什么?
2.TLinkList的长度是多大?
3.TLinkList的链表与第一个结点是如何关联的?

void main(void)
{
    struct  Value v1;
    v1.v = 1;

    TLinkList* list = (TLinkList*)malloc(sizeof(TLinkList));    //创建链表
    LinkListNode* current = (LinkListNode*)list;             //将链表强制类型转换

    printf("list size is %d\n",sizeof(list));
    printf("&list address is %p\n", &list);
    printf("list address is %p\n", list);
    printf("&(list->header) address is %p\n", &(list->header));

    printf("TLinkList size is %d\n", sizeof(TLinkList));
    printf("list->header value is %p\n",list->header);
    printf("&v1 address is %p\n", &v1);
    printf("&(v1->header) address is %p\n", &(v1.header));
    printf("&(list->length) address is %p\n", &(list->length));
    printf("list length value is %d\n", list->length);
    free(list);
}

其输出结果为;

list size is 4
&list address is 0113FBE8
list address is 014CF558
&(list->header) address is 014CF558
TLinkList size is 8
list->header value is 0113FBF4
&v1 address is 0113FBF4
&(v1->header) address is 0113FBF4
&(list->length) address is 014CF55C
list length value is 0

根据输出结果,知道header中存储的为其指向结点的地址,TLinkList的长度为8,其地址可以用下图表示:

原文地址:https://blog.51cto.com/yinsuifeng/2356831

时间: 2024-11-09 01:43:28

关于结构体地址与结构体指针的一些分析的相关文章

入职培训笔记记录--day9(1、指针函数与函数指针、函数指针数组 2、malloc memset 3、递归函数 4、结构体 5、共用体---》大小端 6、枚举)

1.指针函数与函数指针.函数指针数组 指针函数:返回值为指针的函数 char *fun() { char str[] = "hello world"; return str; } int main() { char *p = fun(); puts(p); return 0; } 编译时,会出现警告,返回了一个已经被释放掉的内存空间的首地址解决方法:1.static 2.char *str = "hello world"; 3.malloc 注意:使用完后要free

一维数组,二维数组,三维数组,数组与指针,结构体数组,通过改变指针类型改变访问数组的方式

 打印数组中的每个元素,打印每个元素的地址: #include <stdio.h> #include <stdlib.h> void main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int *p = a; p < a + 10;p++)  //指针类型决定4个字节 { printf("\n%p,%d", p, *p); } getchar(); } 指针数组 #inclu

c结构体里的数组与指针

/* 訪问成员数组名事实上得到的是数组的相对地址.而訪问成员指针事实上是相对地址里的内容 */ struct buf_str { int length; char buf[0]; }; struct foo { buf_str* pbuf; }; void test_funny() { foo f = {0}; printf("%x\n", f.pbuf); printf("%x\n", &f.pbuf->length); printf("%

由结构体成员地址计算结构体地址——list_entry()原理详解

#define list_entry(ptr, type, member) container_of(ptr, type, member) 在进行编程的时候,我们经常在知道结构体地址的情况下,寻找其中某个成员的地址:但是知道了成员的地址,如果找到这个结构体对应的地址呢? Linux内核中,获取节点地址的函数是list_entry(),它的宏定义如上所示. 我们再来查找container_of(ptr, type, member)的定义,发现它依然是一个宏定义: #define container

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(

语言中结构体变量和结构体类型的定义

1.结构体类型定义 定义方式1: Typedef struct  LNode {    int  data;  // 数据域    struct LNode   *next;  // 指针域 } *LinkList; 定义方式2: struct  LNode {    int  data;  // 数据域    struct LNode   *next;  // 指针域 }: Typedef struct  LNode  *LinkList; 以上两个定义方式是等价的,是将*LinkList定义

C的日记-结构体变量和结构体数组

[结构体] 定义结构体的两方式    <1>    struct student{};        struct student a={10001,"云中",'M',"北京"};    <2>    struct student{        }a={10001,"云中",'M',"北京"};定义结构体数组a换成a[],struct student stu[3]={{..},{..},{..}};

C语言 结构体(嵌套结构体--结构体数组)

//结构体--嵌套结构体和结构体数组 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _parent{ int num; char name[30]; //结构体内部定义结构体,如果不定义嵌套结构体变量,那么该嵌套结构体的属性则会被当作父结构体的属性 struct son{ int age; char sna

C语言的结构体和C++结构体的区别

关于C++中声明结构体中需要使用构造器创建实例对象的语法: 接着上两个代码截图你就初步体会到C语言的结构体和C++结构体的区别了:     对于右边的C++结构体的使用类似Java,C++,Swift中的类,类中有构造器方法,然后构造器创建这个类的实例对象. 当然Swift中也有一样用法的结构体.毕竟Swfit是集大家之所成的现代语言.