热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于结构体内指针所指向的

#include<stdio.h>#include<malloc.h>#includeSeqList.htypedefunsignedintTSeqLi
#include 
#include 
#include "SeqList.h"

typedef unsigned int TSeqListNode;

typedef struct _tag_SeqList
{
int capacity;
int length;
TSeqListNode* node;
} TSeqList;//定义结构体

SeqList* SeqList_Create(int capacity) // 传递创建的总数   O(1)
{
TSeqList* ret = NULL;//创建结构体指针

if (capacity >= 0)//总数肯定要大于0的
{
ret = (TSeqList*)malloc(sizeof(TSeqList)+sizeof(TSeqListNode)* capacity);
//分配空间一个结构体的空间加上后面数组空间
}

if (ret != NULL)//判断是否创建失败
{
ret->capacity = capacity;
ret->length = 0;
ret->node = (TSeqListNode*)(ret + 1);//创建一个unsigned int 指针
}

return ret;
}

void SeqList_Destroy(SeqList* list) // O(1)//创建void *list;
{
free(list);
}

void SeqList_Clear(SeqList* list) // O(1)//线性表清零
{
TSeqList* sList = (TSeqList*)list;

if (sList != NULL)
{
sList->length = 0;//把长度清零
}
}

int SeqList_Length(SeqList* list) // 得到其线性表长度 O(1)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;

if (sList != NULL)
{
ret = sList->length;//
}

return ret;
}

int SeqList_Capacity(SeqList* list) //总数  O(1)
{
TSeqList* sList = (TSeqList*)list;
int ret = -1;

if (sList != NULL)
{
ret = sList->capacity;
}

return ret;
}
                 //传入结构指针,和数据地址,还有 位置
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // 插入O(n) 
{
TSeqList* sList = (TSeqList*)list;
int ret = (sList != NULL);
int i = 0;

ret = ret && (sList->length + 1 <= sList->capacity);
ret = ret && (0 <= pos);//表示线性表创建成功

if (ret)
{
if (pos >= sList->length)//如果插入位置大于长度
{
pos = sList->length;//就把插入位置放在最后一个
}

for (i = sList->length; i>pos; i--)
{
sList->node[i] = sList->node[i - 1];//向后移动位置,然后插入
}

sList->node[i] = (TSeqListNode)node;//数据就插入这个位置

sList->length++;
}

return ret;
}

SeqListNode* SeqList_Get(SeqList* list, int pos) // O(1) 得到其元素
{
TSeqList* sList = (TSeqList*)list;//又创建一个结构体指针
SeqListNode* ret = NULL;//创建空指针

if ((sList != NULL) && (0 <= pos) && (pos < sList->length))
{
ret = (SeqListNode*)(sList->node[pos]);// (SeqListNode*)(sList->node[pos]);这为毛是地址,不是一个数组中的值吗,这是为毛
}

return ret;
}

SeqListNode* SeqList_Delete(SeqList* list, int pos) // O(n)
{
TSeqList* sList = (TSeqList*)list;
SeqListNode* ret = SeqList_Get(list, pos);
int i = 0;

if (ret != NULL)
{
for (i = pos + 1; ilength; i++)
{
sList->node[i - 1] = sList->node[i];
}

sList->length--;
}

return ret;
}

// (SeqListNode*)(sList->node[pos]);这为毛是地址,不是一个数组中的值吗,大神求解,哇,这然道不是一个值吗

5 个解决方案

#1


没有看到SeqListNode的结构,不过显然是把sList->node[pos]整型值强转成指针了,或许作者用整型变量存储地址了!这是其一
如果SeqListNode是一个unsigned int类型,那么sList->node + pos更合理,也不需要类型转换。

#2


指针还是用指针来存比较好,比竟有16位地址,32位地址,64位地址等不同
楼主可以发下SeqListNode的定义 

#3


注意看 
①、
20行         ret = (TSeqList*)malloc(sizeof(TSeqList)+sizeof(TSeqListNode)* capacity);
28行         ret->node = (TSeqListNode*)(ret + 1);//创建一个unsigned int 指针

②、
75行 int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // 插入O(n) 
{
.
96行 sList->node[i] = (TSeqListNode)node;//数据就插入这个位置
.
}
由这两处可以看出 其存储的确实就对象的指针,获取的时候必然也就是对象的指针喽
同时我可以肯定,在对象释放的时候 肯定还要释放node指针对应的内存,不然就内存泄露了!!!

这是数据结构存储对象的常用方式,一般都是存储指针,并且该指针的对象一般都是动态开辟出来的内存,不然所指对象生命周期结束,被释放了,那么该指针就成野指针了!

#4


引用 3 楼 zhangsongtao123 的回复:
注意看 
①、
20行         ret = (TSeqList*)malloc(sizeof(TSeqList)+sizeof(TSeqListNode)* capacity);
28行         ret->node = (TSeqListNode*)(ret + 1);//创建一个unsigned int 指针

②、
75行 int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // 插入O(n) 
{
.
96行 sList->node[i] = (TSeqListNode)node;//数据就插入这个位置
.
}
由这两处可以看出 其存储的确实就对象的指针,获取的时候必然也就是对象的指针喽
同时我可以肯定,在对象释放的时候 肯定还要释放node指针对应的内存,不然就内存泄露了!!!

这是数据结构存储对象的常用方式,一般都是存储指针,并且该指针的对象一般都是动态开辟出来的内存,不然所指对象生命周期结束,被释放了,那么该指针就成野指针了!
谢谢我已经懂了,我觉得他把数组元素赋值成地址,开始还不如创建一个指针数组int **node来代替那样,这样更容易理解,对吗,我感觉这样更好,请问这样可不可以

#5


引用 4 楼 u011391093 的回复:
Quote: 引用 3 楼 zhangsongtao123 的回复:

注意看 
①、
20行         ret = (TSeqList*)malloc(sizeof(TSeqList)+sizeof(TSeqListNode)* capacity);
28行         ret->node = (TSeqListNode*)(ret + 1);//创建一个unsigned int 指针

②、
75行 int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // 插入O(n) 
{
.
96行 sList->node[i] = (TSeqListNode)node;//数据就插入这个位置
.
}
由这两处可以看出 其存储的确实就对象的指针,获取的时候必然也就是对象的指针喽
同时我可以肯定,在对象释放的时候 肯定还要释放node指针对应的内存,不然就内存泄露了!!!

这是数据结构存储对象的常用方式,一般都是存储指针,并且该指针的对象一般都是动态开辟出来的内存,不然所指对象生命周期结束,被释放了,那么该指针就成野指针了!
谢谢我已经懂了,我觉得他把数组元素赋值成地址,开始还不如创建一个指针数组int **node来代替那样,这样更容易理解,对吗,我感觉这样更好,请问这样可不可以


SeqList* SeqList_Create(int capacity) // 传递创建的总数   O(1)
{
    TSeqList* ret = NULL;//创建结构体指针
 
    if (capacity >= 0)//总数肯定要大于0的
    {
        ret = (TSeqList*)malloc(sizeof(TSeqList)+sizeof(TSeqListNode)* capacity);
        //分配空间一个结构体的空间加上后面数组空间
    }
 
    if (ret != NULL)//判断是否创建失败
    {
        ret->capacity = capacity;
        ret->length = 0;
        ret->node = (TSeqListNode*)(ret + 1);//创建一个unsigned int 指针
    }
 
    return ret;
}
由创建的函数可以知道,node指针的所知内存大小以及数据的数量是动态指定,因为new的时候是一块连续的空间,这样做的目的是方便释放内存。 如果按照你的意思,用一串连续的指针来存储数据,不是不可以,是因为难维护,释放的时候还要便利分别释放。
 提示一点 int **node 可不是数组指针,自己去查查

推荐阅读
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
author-avatar
aaaaaaaaaa本尊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有