结构和其他数据形式

0x01 结构声明

结构声明(structure declaration)描述了一个结构的组织布局。

struct book{char title[MAXTITL];char author[MAXAUTL];float value;
};

该声明描述了一个由两个字符数组和一个float类型变量组成的结构。该声明并未创建实际的数据对象,只描述了该对象由什么组成。
struct,它表明跟在其后的是一个结构,后面是一个可选的标记(该例中是 book),稍后程序中可以使用该标记引用该结构。
我们在后面的程序中可以这样声明:

struct book library;

这把library声明为一个使用book结构布局的结构变量。

#include "stdio.h"#define MAXTITL 30
#define MAXAUTL 30struct book{char title[MAXTITL];char author[MAXAUTL];float value;
};int a;
struct book book2;
int main()
{struct book book1={"Hello","d1l1endh",7.6};printf("title=%s\n",book1.title);printf("author=%s\n",book1.author);printf("value=%f\n",book1.value);return 0;
}

反汇编我们看看结构声明会产生什么:
在这里插入图片描述
struct book相当于一个类型,和int 相似,book2相当于a,结构布局告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。

0x02 定义结构变量

struct book book2;

编译器执行这行代码便创建了一个结构变量book2。编译器使用book模
板为该变量分配空间:一个内含MAXTITL个元素的char数组、一个内含
MAXAUTL个元素的char数组和一个float类型的变量。这些存储空间都与一
个名称book2结合在一起
struct book book2;
是以下声明的简化:

struct book {
char title[MAXTITL];
char author[AXAUTL];
float value;
} book2; 

换言之,声明结构的过程和定义结构变量的过程可以组合成一个步骤。如果打算多次使用结构模板,就要使用带标记的形式;或者,使用typedef。

2.1 初始化结构

初始化一个结构变量(ANSI之前,不能用自动变量初始化结构;ANSI之后可以用任意存储类别)与初始化数组的语法类似:

struct book book1={"Hello","d1l1endh",7.6};
2.2 访问结构成员

使用结构成员运算符——点(.)访问结构中的成员。

0x03 嵌套结构

在一个结构中包含另一个结构

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN];
};struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};int main()
{struct guy fellow={{"Ell","end"},"salmon","programmer",100000};printf("firset=%s\n",fellow.handle.first);printf("job=%s\n",fellow.job);printf("income=%f\n",fellow.income);return 0;
}

在这里插入图片描述

访问嵌套结构的成员,这需要使用两次点运算符。handle是fellow的成员,first是handle的成员

0x04 指向结构的指针

4.1 声明和初始化指针

我们定义一个int类型指针是:

int *p;

结构也是一种类型,所以声明结构体指针很简单

struct guy *him;

struct guy 是一种类型,相当于int,这个语法和其他指针声明一样。该声明并未创建一个新的结构,但是指针him现在可以指向任意现有的guy类型的结构。如果barney是一个guy类型的结构,可以这样写:

him = &barney;

和数组不同的是,结构名并不是结构的地址,因此要在结构名前面加上&运算符。

4.2 用指针访问成员

使用->运算符。
->运算符后面的结构指针和.运算符后面的结构名工作方式相同
如果him == &barney,那么him->income 即是 barney.income

4.3 向函数传递结构的信息

这里我们重点说传递结构的地址和传递结构
传递结构的地址

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN];
};struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};double sum(struct guy *);int main()
{struct guy fellow={{"Ell","end"},"salmon","programmer",100000};double sum_income=sum(&fellow);//printf("firset=%s\n",fellow.handle.first);//printf("job=%s\n",fellow.job);printf("sum_income=%f\n",sum_income);return 0;
}double sum(struct guy *people)
{return (people->income+people->income);
}

在这里插入图片描述
因为结构名不是其地址别名,所以我们必须用&运算符,然后通过->运算符获取值

传递结构

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN];
};struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};double sum(struct guy );int main()
{struct guy fellow={{"Ell","end"},"salmon","programmer",100000};double sum_income=sum(fellow);//printf("firset=%s\n",fellow.handle.first);//printf("job=%s\n",fellow.job);printf("sum_income=%f\n",sum_income);return 0;
}double sum(struct guy people)
{return (people.income+people.income);
}

传递结构直接把结构名当参数就行

0x05 typedef

typedef工具是一个高级数据特性,利用typedef可以为某一类型自定义名称。

typedef unsigned char BYTE;

随后,便可使用BYTE来定义变量:

BYTE x, y[10], * z;

该定义的作用域取决于typedef定义所在的位置。

0x06 函数与指针

声明一个函数指针时,必须声明指针指向的函数类型。为了指明函数类型,要指明函数签名,即函数的返回类型和形参类型。

void ToUpper(char *); // 把字符串中的字符转换成大写字符

ToUpper()函数的类型是“带char * 类型参数、返回类型是void的数”。

void (*pf)(char *);  // pf 是一个指向函数的指针

第1对圆括号把*和pf括起来,表明pf是一个指向函数的指针
把**函数名ToUpper替换为表达式(*pf)**是创建指向函数指针最简单的方式。
所以,如果想声明一个指向某类型函数的指针,可以写出该函数的原型后把函数名替换成(*pf)形式的表达式,创建函数指针声明。

#include "stdio.h"void add(int a,int b);void main(void)
{int a=4,b=3,s=0;void (*funp)(int a,int b);funp=add;(*funp)(a,b);funp(a,b);}void add(int a,int b)
{printf("a+b=%d\n",a+b);}

在这里插入图片描述
声明一个函数指针时,必须声明指针指向的函数类型。包括返回值、参数,如果想声明一个指向某类型函数的指针,可以写出该函数的原型后把函数名替换成(*pf)形式的表达式,这样就声明好一个函数指针了。用函数指针调用函数是有两种方式:

  • 指针名(参数)
  • (* 指针名)(参数)
    我们反汇编看一下
9:        void (*funp)(int a,int b);
10:       funp=add;
00410B2D C7 45 F0 0F 10 40 00 mov         dword ptr [ebp-10h],offset @ILT+10(_add) (0040100f)
11:       (*funp)(a,b);
00410B34 8B F4                mov         esi,esp
00410B36 8B 45 F8             mov         eax,dword ptr [ebp-8]
00410B39 50                   push        eax
00410B3A 8B 4D FC             mov         ecx,dword ptr [ebp-4]
00410B3D 51                   push        ecx
00410B3E FF 55 F0             call        dword ptr [ebp-10h]
00410B41 83 C4 08             add         esp,8
00410B44 3B F4                cmp         esi,esp
00410B46 E8 E5 06 FF FF       call        __chkesp (00401230)

可以看出,把首地址赋值给我们的函数指针,也就是把函数首地址放到dword ptr [ebp-10h]里,调用的时候直接call dword ptr [ebp-10h],和平常调用函数一样

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java StringBuffer char charAt(int index)方法与示例

StringBuffer类char charAt(int index) (StringBuffer Class char charAt(int index)) This method is available in package java.lang.StringBuffer.charAt(int index). 软件包java.lang.StringBuffer.charAt(int index)中提供了此方法。 This method is used to return the …

Form验证

代码写 N 久了,总想写得别的。这不,上头说在整合两个项目,做成单一登录(Single Sign On),也有人称之为“单点登录”。查阅相关文档后,终于实现了,现在把它拿出来与大家一起分享。或许…

添加LinkServer的两句代码

sp_addlinkedserver linkserver,,SQLOLEDB,linkserver.comsp_addlinkedsrvlogin linkserver,false,null,sa,asdf第一句是添加一个名字为linkserver的链接服务器 地址是linkserver.com第二句是针对第一句添加的Linkserver添加一个访问帐号两句不能同时执行 要第一句执行成功后执…

数组的基本查找

package asdasqq; import java.util.*; public class jibenchazhao { public static void main(String[] args) { int [] arr{11,22,33,44,55,66,77}; Scanner wsqnew Scanner(System.in); int qwsq.nextInt();//输入q,即为查找的数; int index g…

Cobaltstrike4.0系列教程(一)----简介与安装

0x01-Cobaltstrike简介 Cobalt Strike是一款美国Red Team开发的渗透测试神器,常被业界人称为CS。这款神器许多大佬们都已经玩的很6,我一个菜鸡玩的略有心得,因此写一下自己的Cobaltstrike系列文章,希望给各位一点帮助。 最近这个…

c ++类成员函数_仅使用C ++创建具有公共数据成员的类

c 类成员函数Let’s understand 让我们来了解 What is data member? 什么是数据成员? Any variable declared inside the class in known as data member of the class. 在类内部声明的任何变量,称为类的“数据成员”。 What is public data member…

转:php.ini中文版

[PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而php.ini的设置更改可以反映出相当的变化, ; 在使用新的PHP版本前,研究一下php.ini会有好处的 ;;;;;;;;;;;;;;;;;;; ; 关于这个文件 ; ;;;;;;;;;;;;;;;;;;; ; 这个文件控制了PHP许…

qt 试用 (3)配置编译源代码及调试

qt 试用 (3)配置编译源代码及调试qt creater是一个集成ide,像vc一样容易使用,所以首先下载带qt creater的qt sdk Offline installer - 1.4 GB http://qt.nokia.com/downloads/sdk-windows-cpp-offline这里的lib没有pdb和源代码…

两数的最大公约数算法基础及优化

最大公约数算法师从辗转相除法(欧几里得算法)时间复杂度更相减损术(《九章算术》)时间复杂度二分化更相减损术思路优化时间复杂度师从 本篇是观Vita君算法视频后总结,他是bilibili一位小up主:小学生Vita君…

cobaltstrick4.0系列教程(2)---用户接口

0x01 概述 Cobalt Strike 用户接口分为两部分。接口的顶部是会话或目标的视觉化展示。接口的底部展示了每个你与之交互的 Cobalt Strike 功能或会话的标签页。你可以点击这两部分之间的区域、按你的喜好重新调整这两个区域的大小。 0x02 工具条 Cobalt Strike 顶部的工具条…

java类名与文件名_为什么Java文件名必须与公共类名相同?

java类名与文件名The question is that "Can we keep different names for java class name and java file name?" 问题是“我们可以为Java类名和Java文件名保留不同的名称吗?” Yes, we can keep the different name for the java filename and java c…

玩什么都别玩暧昧

暧昧 这个介于朋友与情人间的关系 能给予寂寞的人些须安慰与短暂的幸福感 暧昧 没有任何承诺 彼此都不向对方许下诺言 没有甜言蜜语 没有海誓山盟 却在彼此悲伤难过的时候 给予彼此依靠 也许 这种关系是最好的 因为它不虚假 它没有骗人的谎言 因为彼此没有承诺 两个人 可以一起…

快速幂模

快速幂模简述师从普通思路缺陷一:溢出缺陷二:运算次数多二分化快速幂模简述 计算 ana^nanmod p 师从 本篇是观Vita君算法视频后总结,他是bilibili一位小up主:小学生Vita君 正所谓“生乎吾后,其闻道也亦先乎吾&#…

《那些年啊,那些事——一个程序员的奋斗史》——31

“我们再重新找房吧?”伍定轩对段伏枥说道。“为什么?”段伏枥突然觉得奇怪,为何伍定轩会突然提出这个问题。“你看我的仙人掌。”伍定轩指了指摆在电脑旁边的一盆仙人掌。当初伍定轩决定买这小盆仙人掌的时候,也是从网上听人说&a…

数煤球

煤球数目 有一堆煤球,堆成三角棱锥形。具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形)&…

cobalt strick 4.0系列教程(3)---数据管理

0x01 概述 Cobalt Strike 的团队服务器是行动期间 Cobalt Strike 收集的所有信息的中间商。Cobalt Strike 解析来自它的 Beacon payload 的输出,提取出目标、服务和凭据。 如果你想导出 Cobalt Strike 的数据,通过 Reporting → Export Data 。Cobalt S…

JavaScript中的交互式网页/事件处理

Programming languages like C, C etc are all based on synchronous coding approach i.e. the execution takes place from top to bottom in a linear manner. 诸如C,C 等编程语言均基于同步编码方法,即执行以线性方式从上到下进行。 But JavaScript…

2008来了,搬个凳子先

此帖为证. 转载于:https://www.cnblogs.com/margiex/archive/2008/01/01/1022098.html

题目收藏夹(自用)

题目收藏夹(自用) 计数质数 【埃氏筛】【线性筛】

calayer 与uiview

研究Core Animation已经有段时间了,关于Core Animation,网上没什么好的介绍。苹果网站上有篇专门的总结性介绍,但是似乎原理性的东西不多,看得人云山雾罩,感觉,写那篇东西的人,其实是假 设读的人…