上一篇基础链接https://www.cnblogs.com/xuexidememeda/p/12283845.html

主要说一下链表里面双重指针

先说一下结构体

typedef struct LNode
{
int data;
struct LNode *next; }LNode, *LinkList; typedef 把这个结构体定义一个别的名字
LNode==LNode 类型 LinkList==LNode* 类型 *LinkList 是函数指针..........这个写法我也很懵逼没法从内存角度理解 最后也有简单介绍函数指针
你不定义typedef一样直接可以用LNode 就是写的时候不方便 但是我觉得对新手易于理解

  


先上总代码 两个main12是测试函数 自己改着玩

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<malloc.h>
using namespace std; typedef struct LNode
{
int data;
struct LNode *next; }LNode, *LinkList; //--------------后插法创建单链表 ------------------
void CreateList_E(LinkList &head, int n)
{
int i;
LinkList pnew;
LinkList pend;//定义最后的节点指针;
//先建立头结点,数据为空; head = new LNode;
head->next = NULL;
pend = head;//头结点是最后的节点 ;
for (i = ; i < n; i++)
{
pnew = new LNode;
printf("请输入第%d个节点的数据:\n",i);
scanf_s("%d", &pnew->data);
pnew->next = NULL;
pend->next = pnew;
pend = pnew; }
} void CreateList_E1(LNode* &head, int n)
{
int i;
LinkList* ptr;
LinkList pnew;
LinkList pend;//定义最后的节点指针;
//先建立头结点,数据为空; head = new LNode; //返回的是分配空间的首地址LNode* 类型
head->next = NULL;
pend = head;//头结点是最后的节点 ;
for (i = ; i < n; i++)
{
pnew = new LNode;
printf("请输入第%d个节点的数据:\n", i);
scanf_s("%d", &pnew->data);
pnew->next = NULL;
pend->next = pnew;
pend = pnew;
} }
//双重指针 头结点貌似必须在外面创建??
void CreateList_E1(LNode** lnode, int n)
{
LinkList head = *lnode;
head->next = NULL; for (int i = ; i < n; i++)
{
LNode* pnew = new LNode;
printf("请输入第%d个节点的数据:\n", i);
scanf_s("%d", &pnew->data);
pnew->next = head->next;
head->next = pnew;
} } //------------------打印链表----------------
void PrintList(LinkList head)
{
LinkList item;
item = head;
item = item->next;//这一步不是必须要做的,为了跳过头结点(没有数据)
while (item != NULL)
{
printf("----%d----\n", item->data);
item = item->next; }
}
void main1()
{ LNode* L = NULL;
int n;
printf("输入要创建的链表结点个数:\n");
scanf_s("%d", &n);
CreateList_E1(L, n);
printf("\n打印结果!\n");
PrintList(L); } void main2()
{
LNode* temp= new LNode;
LNode** L= &temp;
int n;
printf("输入要创建的链表结点个数:\n");
scanf_s("%d", &n);
CreateList_E1(L,n);
printf("\n打印结果!\n");
PrintList(*L); }
int _tmain(int argc, _TCHAR* argv[])
{
//main1();
main2();
}

说一下创建+赋值链表函数(自己看着前面的看)

void CreateList_E(LinkList &head, int n)==void CreateList_E1(LNode* &head, int n)

LinkList 的类型其实是LNode* 类型 然后&head 是传参引用?好像是这样的(忘怎么说了)  如果你不带&符号只能在本函数打印出来赋值语句 在封装的函数是无法打印的

跟你的swap学过一个函数交换值他真实的值还是不变,多数人疑问就是我传的可是一个指针类型,他是一个地址呀!为什么还是传不过去呢 因为你的指针地址是在栈中分配空间用完就销毁呢( CreateLis函数运行结束main函数无法找到原来分配的地址)    只要头结点是在main函数中分配的那么他以后的指针在哪分配都没问题的..... 看似简单的一个问题,要 真正弄懂其实要看编译器怎么办的就是看汇编

(本人汇编基础不扎实自学的以后博客再补上!!)

唯一确定的是不加&函数call return 之后会 main函数无法得到指针的地址

void CreateList_E1(LNode** lnode, int n)   这个和CreateList_E(LinkList &head, int n) 差不多因为我们之前说过 加一个& 相当于类型后加个*


其实你完全可以想简单点你完全可以把指针类型当成类似int之类的类型 ,比如  要实现 void swap1(int a, int b)交换a b的值  我们都知道无法交换值  要交换值有两种方法 一种是void swap1(int* a, int* b)  一种是引用   所以要使用指针的指针


函数指针...............简单例子

例如:

class Test
{
private:
int x;
int y;
public:
Test(){ x = ; y = ;}
void Pintf() { cout << x << " " << y << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
Test a;
a.Pintf();
int* b = (int*)&a;
//cout << *b;
cout << &a << endl; //如果直接输出a的内存的话 是0001 0002 //没法直接输出必须用指针查看值 short* c = (short*)&a;
char* d = (char*)&a;
cout << *d << endl;
cout << *c<<endl;
cout <<b;
getchar(); /* 17: Test a;
00972CC8 8D 4D F0 lea ecx,[a] ecx 0x0108FCB0 this 指针
00972CCB E8 E5 E7 FF FF call Test::Test (09714B5h)
18: a.Pintf();
00972CD0 8D 4D F0 lea ecx,[a]
00972CD3 E8 7A E6 FF FF call Test::Pintf (0971352h)
19: int* b = (int*)&a;
00972CD8 8D 45 F0 lea eax,[a]
00972CDB 89 45 E4 mov dword ptr [b],eax
20: //cout << *b;
21: cout << &a<<endl;
00972CDE 8B F4 mov esi,esp
00972CE0 68 ED 13 97 00 push 9713EDh
00972CE5 8B FC mov edi,esp
00972CE7 8D 45 F0 lea eax,[a]
00972CEA 50 push eax
00972CEB 8B 0D F8 10 98 00 mov ecx,dword ptr ds:[9810F8h]
00972CF1 FF 15 FC 10 98 00 call dword ptr ds:[9810FCh]
00972CF7 3B FC cmp edi,esp
00972CF9 E8 40 E6 FF FF call __RTC_CheckEsp (097133Eh)
00972CFE 8B C8 mov ecx,eax
00972D00 FF 15 9C 10 98 00 call dword ptr ds:[98109Ch]
00972D06 3B F4 cmp esi,esp
00972D08 E8 31 E6 FF FF call __RTC_CheckEsp (097133Eh) */ }
Test a; 这个a 到底是什么? 其实就是这个类的开头 比如这个开头存的就是0001 0002 x,y  我原来认为a存的 一直是一个地址指向 00010002这位置
假如test 类里面有虚函数 例如 virtual void Function_4() 则 Test a 中 a的首地址开头存的就是一个虚表函数 总地址例如是A (意思是 *A 是你第一个虚函数 *(A+1)是你第二个虚函数)
如果你多继承而且父类中有虚函数则比如有2个则有2个虚表

C++ 结构体指针理解的更多相关文章

  1. Delphi 中的结构体与结构体指针

    好多程序都给结构体变量设定了一个结构体指针 例如: PAbc = ^TAbc; TAbc = record a: string[10]; b: string[5]; c: string[1]; end ...

  2. c语言结构体指针初始化

    今天来讨论一下C中的内存管理. 记得上周在饭桌上和同事讨论C语言的崛起时,讲到了内存管理方面 我说所有指针使用前都必须初始化,结构体中的成员指针也是一样 有人反驳说,不是吧,以前做二叉树算法时,他的左 ...

  3. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  4. C语言结构体指针初始化(转)

    reference: https://www.cnblogs.com/losesea/archive/2012/11/15/2772526.html 今天来讨论一下C中的内存管理. 记得上周在饭桌上和 ...

  5. Android JNI编程(六)——C语言函数指针、Unition联合体、枚举、Typedef别名、结构体、结构体指针

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:函数指针 1.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...

  6. 解惑结构体与结构体指针(struct与typedef struct在数据结构的第一道坎)

    /* 数据结构解惑01  在数据结构中会看到 typedef struct QNode { QElemType data; //数据域 struct QNode *next; //指针域 }QNode ...

  7. 对offsetof、 container_of宏和结构体的理解

    offsetof 宏 #include<stdio.h> #define offsetoff(type, member)      ((int)&((type*)0)->me ...

  8. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  9. ctypes 操作 python 与 c++ dll 互传结构体指针

    CMakeLists.txt # project(工程名) project(blog-3123958139-1) # add_library(链接库名称 SHARED 链接库代码) add_libra ...

随机推荐

  1. netty(六) buffer 源码分析

    问题 : netty的 ByteBuff 和传统的ByteBuff的区别是什么? HeapByteBuf 和 DirectByteBuf 的区别 ? HeapByteBuf : 使用堆内存,缺点 ,s ...

  2. Java数字和字符的对照关系表

    /* 数字和字符的对照关系表(编码表): ASCII码表:American Standard Code for Information Interchange,美国信息交换标准代码. Unicode码 ...

  3. html解析のBeautifulSoup

    引子: 使用python爬虫对爬取网页进行解析的时候,如果使用正则表达式,有很多局限,比如标签中出现换行,或者标签的格式不规范,都有可能出现取不到数据,BeautifulSoup作为一个专门处理htm ...

  4. VScode Vim插件快速上手与配置

    快速安装: 打开market place,搜索vim即可安装. 基本改建与配置说明: 方向键: 用I k j l表示光标上下左右,需要编辑visual mode和normal mode { " ...

  5. LeetCode练题——53. Maximum Subarray

    1.题目 53. Maximum Subarray——Easy Given an integer array nums, find the contiguous subarray (containin ...

  6. PyQt5控件支持拖拽方法

    让控件支持拖拽动作A.setDragEnable(True) 设置A可以拖动B.setAcceptDrops(True) 设置B可以接受拖动B需要满足两个事件1.dragEnterEvent 将A拖到 ...

  7. Docker Learning Notes

    Docker简介 是什么 问题:为什么会有docker出现 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置.作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的 ...

  8. @ResponseBody是如何起作用的

    前言 最近参与的项目中,接口中返回的日期格式不对,发现项目中配置了fastjson作为spring的数据转换器,于是使用了fastjson的字段格式化转换注解 发现不起作用.这让我很疑惑,然后在fas ...

  9. 安装go和goland

    1.建议去go语言中文网下载,网址:https://studygolang.com/dl ,下图是下载页面及包介绍 2.Windows版安装 3.在cmd命令行窗口输入“go version”可以查看 ...

  10. Ubuntu新手指引-软件包apt命令使用

    看到这个博客,你十有八九是刚接触Ubuntu,不知从何下手.Ubuntu社区虽然现在不活跃,但里有很多文,可以帮助你快速上手,比如Ubuntu中文社区新手指引. 软件包的管理常常涉及root权限,普通 ...