C++ 结构体指针理解
上一篇基础链接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++ 结构体指针理解的更多相关文章
- Delphi 中的结构体与结构体指针
好多程序都给结构体变量设定了一个结构体指针 例如: PAbc = ^TAbc; TAbc = record a: string[10]; b: string[5]; c: string[1]; end ...
- c语言结构体指针初始化
今天来讨论一下C中的内存管理. 记得上周在饭桌上和同事讨论C语言的崛起时,讲到了内存管理方面 我说所有指针使用前都必须初始化,结构体中的成员指针也是一样 有人反驳说,不是吧,以前做二叉树算法时,他的左 ...
- C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com
原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...
- C语言结构体指针初始化(转)
reference: https://www.cnblogs.com/losesea/archive/2012/11/15/2772526.html 今天来讨论一下C中的内存管理. 记得上周在饭桌上和 ...
- Android JNI编程(六)——C语言函数指针、Unition联合体、枚举、Typedef别名、结构体、结构体指针
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:函数指针 1.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...
- 解惑结构体与结构体指针(struct与typedef struct在数据结构的第一道坎)
/* 数据结构解惑01 在数据结构中会看到 typedef struct QNode { QElemType data; //数据域 struct QNode *next; //指针域 }QNode ...
- 对offsetof、 container_of宏和结构体的理解
offsetof 宏 #include<stdio.h> #define offsetoff(type, member) ((int)&((type*)0)->me ...
- C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...
- ctypes 操作 python 与 c++ dll 互传结构体指针
CMakeLists.txt # project(工程名) project(blog-3123958139-1) # add_library(链接库名称 SHARED 链接库代码) add_libra ...
随机推荐
- react组件之间传值方式
1.父向子(通过props传值) 2.父向更深层的子(通过context传值) 3.子向父(通过回调函数传值:在父组件中创建一个函数来接收子组件传过来的参数值,通过父组件将这个函数做为子组件的属性传递 ...
- Xcode 编译运行旧项目报错解决之路
运行几年前做的项目,发现各种编译报错,一个一个解决记录下: 1.Xcode(Xcode9)编译运行报错,但是在 issue navigatior 栏看不到错误信息: 解决方案:在 show repor ...
- 关注Ionic底部导航按钮tabs在android情况下浮在上面的处理
Ionic是一款流行的移动端开发框架,但是刚入门的同学会发现,Ionic在IOS和android的底部tabs显示不一样.在安卓情况下底部tabs会浮上去. 如下图展示: 网上也有很多此类的解决方案 ...
- eclipse配置tomcat后修改server.xml文件(如编码等)无效问题
我们用eclipse配置好tomcat后,在处理中文乱码或是配置数据源时,我们要修改Tomcat下的server.xml等文件. 修改后重启Tomcat服务器时发现xml文件又被还原了. 因为Tomc ...
- ASP.NET Core搭建多层网站架构【1-项目结构分层建立】
2020/01/26, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[1-项目结构分层建立] 文章目录 此分支项目代码 ...
- Bugku-CTF社工篇之简单的个人信息收集
- PHPStorm 使用 Xdebug
一.下载xdebug xdebug官网:https://xdebug.org/download.php 在选择下载哪个版本的xdebug的时候需要注意了,下面有两种方法,让你准确的下载自己环境对应的x ...
- web优化(一 前端)
当我们在浏览器地址栏中输入一个URL的时候,网页开始请求,我们在页面上看到的内容就是许多个HTTP请求从服务器返回的数据展示,这些展示的快慢很大程度依赖前端的优化,怎样做好前端的优化,我这里总结了几点 ...
- Unity3D~纹理格式
因为之前自己从来没有好好看过这部分,一直都是用的DXT压缩图片,结果发现原来ios是不支持DXT的, 还不知道我项目那么卡是不是这部分引起的, 但愿是~这样应该就可以解决游戏在ios上只有6.8帧的问 ...
- SQL SERVER 语法汇总
一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备 ...