你好, 欢迎回来｡
我想提供解决方案 上一个挑战｡
演示您如何
可以将指针作为结构内部的元素, 还可以 在两个函数指针之间传递结构
让我们来看看代码 块, 创建新项目｡
这将是一个控制台 应用程序,
我们将把这个结构命名为指针示例｡
如果你还记得
这基本上只是一种产品类型 存储项目名称､ 数量､ 价格和金额的结构｡
物品的名字 字符指针｡
你本来打算 基本上是数量与价格的乘积｡
然后我们有两个函数 它会将指向结构的指针作为参数｡
所以我们首先要做的 我们要做的就是创建我们的结构｡
我之前提到过, 但是
全局创建结构是很好的, 因为如果你想 在多个功能中使用它｡
创建结构 才真正定义了它｡
您没有分配任何内存｡
所以没什么坏处 将其放到全球｡
他们通常会进去 头文件｡
为了创造一个结构, 我们只说结构体｡
我们称之为 我们将有四个元素｡
我们将有一个角色 指针, 我们将其命名为item
name｡
我们会有一个数量｡
我们将有一个花车 价格,
我们将有一个浮动的金额｡
这就是我们如何定义 我们的结构, 非常基本｡
在主函数中, 我们 我想为结构类型创建一个变量, 还想创建一个指针｡
所以我们要做的第一件事 我们只想用结构体的名称来表示struct item
那么我们就调用这个项目｡
而这只是 从而产生奇数指针｡
这将分配内存 结构中的四个变量和元素｡
所以我们要创建指针 现在我们可以直接说struct item｡
我们会说p项 因为我们通常用前缀p来命名指针｡
所以我们说星号, 我们称之为p项｡
然后在下一行 我们只想给指针项赋值｡
因此我们需要使用 地址为, 我们称之为项｡
这里我们有记忆 分配给指针结构中的元素｡
我们没有任何记忆
分配给我们的字符指针, 也就是我们的项目名称, 所以这是下一步｡
现在你可能会问为什么我们需要 以创建项结构｡
我们真的不知道｡
我们可以创建一个指针 指针只会为那个结构项指针创建内存｡
它将为
int和floats, 但我们仍然需要分配项名｡
我喜欢这样做是因为 这通常是一种好的做法｡
通常您会使用 第一个item结构是初始化它, 所以
将进行一些初始化｡
但我们不需要这样做｡
所以我们要做的第一件事就是 为项目名称分配内存｡
所以我们基本上可以使用 特殊运算符来访问元素（如果是指针）｡
请记住, 对于 是指针,
您可以使用破折号然后大于符号 可用于访问元素｡
否则, 您必须取消引用 用于访问元素的指针｡
我们可以这样做 这在括号内｡
我们可以取消指针的引用,
因此我们必须执行类似于星星p item操作, 然后使用 访问元素的点｡
这是完全正确的 做这样的事｡
但这是一种额外的语法 你其实并不需要｡
所以c有特殊的语法 只要您的结构是指标, 就可以使用
想要访问元素｡
你只要说出名字 然后使用破折号, 然后大于｡
在这种情况下, 我们希望 为项目名称分配内存｡
所以我们要给它赋值 从malloc函数返回｡
请记住, malloc函数 传回void指标｡
所以我们必须铸造它 一个角色星星｡
但我们可以调用malloc 比如malloc, 然后是我们要创建的字节的大小｡
在这种情况下, 我们就说30, 我们将它乘以char的大小,
以防char是 在不同计算机上有不同大小｡
这将分配 我们的项目名称的内存｡
我们需要这样做, 因为项名称 是结构内部的指标｡
它没有记忆 将其分配给其他结构时,
会出现这种情况｡
所以我们必须这么做｡
现在你想要的第一件事 在分配完内存之后要做的就是检查malloc｡
因此我们需要检查此处是否为null｡
我们只要说如果p项, 如果 也就是说它是空的
否则, 你会说如果没有, 你可以 就说返回或退出可能会更好,
如果我们 无法分配内存, 你可以把它传递给负一
否则, 我们要读入一个 所以我们要创建一个函数｡
我们要讨论的函数 被称为读取项｡
让我们建立一个函数声明 在建筑物的上方｡
它只是阅读数据 我们传递给它的结构体｡
它不会返回任何数据｡
所以我们可以说读项 它需要一个结构体, 也就是指针
所以这是一个结构项, 星号I.
现在我们可以将其设为常数 所以价值观会有所改变,
但我们正在改变价值观｡
但是我们可以说常量结构体 它所指向的指针的值将无法更改｡
如果我们在 星号表示地址不能更改或正确
在星号前面类似名字后面的东西｡
也就是说地址不能
更改, 但这是多余的, 因为我们传递的是副本值｡
我们有已读项目｡
当我在这里的时候我可能 我的印刷品也一样｡
这就是函数 声明､ 函数原型｡
在这里, 这将是非常 类似, 也取一个指针｡
如果你想的话可以有空间 在星号后面吗
现在我们可以定义读取 项｡
这将是 然后计算总金额｡
所以我们可以说void read 项目, 有我们的指标｡
在这里, 我们只想 使用一些scanfs｡
我们要打印一些信息 以告诉用户输入信息｡
所以我们要输入 产品名称, 然后读入它｡
所以我们会说scanf, 我们有一个指向结构体的指针, 所以我们可以访问它 使用破折号,
然后大于｡
我们想读scanf的文章, 产品名称是一个字符缓冲区｡
所以我们想说的是 然后我们会说I, 我们会把它存储在项目名称中｡
我们可以回去用 intellisense只转到项目名称｡
我们不必使用 运算符的地址, 因为它是字符指针｡
然后, 我们要打印输出并获取
价格, 可能需要在此处添加一些换行符, 请输入价格｡
我们要储存 在结构中｡
所以再一次, 价格是浮动的｡
所以我要说是百分之f, 但是 我们也会访问它因为它是指针 请使用破折号,
然后使用大于号｡
不过这次我们要 我们需要得到它的地址所以我们要 因为price不是指针,
所以在它前面放一个“&”号｡
然后我们要做 数量也是一样｡
所以数量是一个整数｡
所以我们可以说% d,
我们仍然需要 来获取它的地址, 但我们想把它存储在一个不同的元素中, 我们要按数量储存｡
既然我们已经存储或询问了
用户输入三项信息, 现在我们可以 实际计算金额, 在金额中存储一些东西｡
金额正好是 数量乘以价格｡
所以我们还是要访问 使用我们的语法创建一个结构, 我们需要对其进行强制转换,
并对其进行签名 数量乘以价格｡
这就是读取项函数｡
采用结构指针｡
所以当我们修改这个指针时 在读取项内部,
它将在函数外部被修改.
所以不管我们用什么结构 传递给这个函数, 它会被修改｡
它会储存所有 项目､ 项目名称､ 价格､
数量和金额｡
以便读入数据｡
此时, 您可能希望
您可能希望在此之前进行编译和测试｡
但我们现在可以称之为读取项 方法并将其传递到我们创建的结构中｡
所以我们可以说读项, 我们可以说是p项｡
我们不必通过 地址, 因为它是一个指针,
所以我们只需要传入我们的结构｡
然后接下来我们 我们能做的就是打印出来｡
这将告诉你 数据已保存,
p项在函数内部被修改 它被保存在主函数之外
实际上已经保存了这些值｡
因此, 我们可以说打印项目传递 然后我们可以定义打印项目函数｡
印刷品非常基本｡
它不返回任何内容, 所以我们说void和print
item需要一个指针｡
所以我们就说结构项星星 我, 随便你怎么命名｡
然后我们打印出数据 为传入的结构｡
所以我们会这样做 打印名称百分比､ 项目名称､ 价格､
数量和 然后格式化数据｡
我们最后一件事 在我们打印出数据后, 非常重要的免费功能｡
我们得免费打电话 我想释放为项目名称分配的内存｡
所以我们可以说自由p项 然后访问项目名称｡
我们不想把整个
结构, 因为整个结构将在 堆栈｡
我们只是想解放我们所奴役的｡
我们只分配了项 所以我们释放它, 然后从主目录返回｡
所以我们继续 试着建造这个｡
我们确实有一个错误｡
让我们看看它是否写着struct item星星｡
所以我们犯了个错误 在结构之上定义功能｡
但是取一个 参数作为结构类型｡
所以我们必须有一个结构 在上面定义的地方使用它｡
所以我把函数 向下到第12和13行｡
现在我们可以编译了｡
让我们继续运行此程序｡
让我们看看我们在这里得到了什么｡
我们还有一个错误｡
你必须确保你 检查p项是否为空｡
如果你只是说如果p项为 真的, 永远都是真的｡
所以你可以选择 它不为真,
带有not符号, 表示它不是null或您 可以检查它是否为空｡
所以我在这里加了个空值｡
所以现在我们运行它, 我们 应该可以走了｡
我们可以输入产品名称｡
我们会说是连环杀人案 假设价格为1｡ 99.
我们会说我们有五个｡
现在我们打印出来, 我们说是99美元｡
5, 总金额为9｡ 95.
价格虽然我不喜欢 如何打印出价格｡
所以我们来解决这个问题｡
在我们的印刷品中, 我们可以说 price dor 2 f
float, 现在我们看起来会好一点, 然后我们运行它｡
我们会得到一点 格式更好一些｡
他们四个人现在 看起来好多了, 一切都好了
同样, 基本程序使用 结构和指针｡
我们在顶部创建了结构｡
我们有一个成员包含
指针, 这样做非常有效, 因为我们可以 而不是字符数组｡
我们有两个func声明, 读取项打印接受指针项析构｡
然后我们创建指针 并将其分配给main中的一个常规结构｡
我们在第22行分配内存｡
我们要确保记忆 分配成功, 如果不是,
则退出程序｡
然后我们叫我们的两个 获取指向结构的指针的函数,
将它们传入｡
最后但并非最不重要的是, 我们释放内存然后退出程序｡
其功能包括 非常简单｡
你拿着那个教鞭｡
您可以使用 破折号, 然后大于｡
然后你就得到了 对于没有指针作为元素的scanfs, 它是｡
基本上就是这样｡
我保存此程序, 你看一下｡
如果你有任何问题, 请告诉我｡ -谢谢—谢谢