关于C++的一个问题,为啥下面这段代码如果不申请空间就成功不了呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C++的一个问题,为啥下面这段代码如果不申请空间就成功不了呢?相关的知识,希望对你有一定的参考价值。

void Init(queue **pTop)

*pTop = (queue *)malloc(sizeof(queue)); //为甚么要申请一块空间?
(*pTop)->pTail = NULL;
(*pTop)->pTop = NULL;
(*pTop)->nCount = 0;

这就是queue指针和queue实例之间的区别,指针只是指明了可用queue实例的起始地址,这个起始地址在程序一开始是无效的,需要用户将它赋值指向一个可用的queue实例才行。而可用的queue实例需要用户自己设计程序申请出来,这就是程序中用malloc函数完成的工作。

举个例子:住房有门牌号,按照门牌号可以访问住客或者住进新客人,这个门牌号就是指针,当没有拥有住房时,门牌号是虚的,即使使用也不是你被允许访问的,需要拥有住房,并且获得门牌号才能用门牌号进行操作(访问或入住)。

参考技术A

首先pTop是二级指针,*pTop是二级指针一次解引用,仍然是指针(一级指针),指针是不能储存queue类型的值的,它只能存放queue类型的地址。

因此需要调用malloc函数申请空间,配合着申请的空间,我们才可以对这个指针进行有意义的操作:

如果指向一个基本类型,那就可以对指针解引用取值

如果指向一个对象或结构,那就可以用->进行成员访问

如果指向一个数组,那就可以用指针偏移进行取值

malloc的函数原型是:void *malloc(unsigned int size)(注意返回类型是void,意味着它可以且必须被转换成任意类型才可以使用)

下面解释一下这个过程:

malloc在内存中申请一块空间,然而要怎么访问这个空间呢?需要用一个指针指向该内存,才有可能访问,因此代码中的*pTop(你所定义的pTop是一个二级指针,所以*pTop是一级指针,因此用*pTop指向分配的内存没有问题)就是这样一个用法。

但是有了指针还不够,应该怎样去读写空间中的数据呢?是作为int,char?或者是更复杂的类型(比如你程序中的queue类型),因此你必须强制转换为特定的类型(就如你代码中的“(queue*)”强制类型转换),才能知道告诉编译器按照什么类型来读写这个空间(每个类型的读写方式都是不一样的)

所以*pTop = (queue *)malloc(sizeof(queue));的解释其实分为以上3个步骤:分配空间,强制转换空间的类型(告诉编译器该以何种形式处理),使指针指向空间(以得访问)

==========

另外,C++中建议用new和delete代替malloc和free

malloc和new都是申请一块内存空间并使指针指向空间,但是new会调用类的构造函数,可以初始化某些类的成员(有时这是必要的),而malloc只是单纯分配空间和指针赋值,而不会进行任何额外操作。free和delete也是同理(delete调用析构函数

另外new和delete不需要头文件,直接可以使用,比较方便

但是new和delete确实会比malloc和free效率低一丢丢,但是随着硬件的发展,这一丢丢已经是可以完全忽略不计的了。所以还是建议new和delete

本回答被提问者采纳
参考技术B 关于C++的一个问题,为什么下面这段代码如果不申请空间就成功不了呢?

或者是无效的 C++:为啥这段代码会编译?

【中文标题】或者是无效的 C++:为啥这段代码会编译?【英文标题】:or is not valid C++ : why does this code compile?或者是无效的 C++:为什么这段代码会编译? 【发布时间】:2010-11-28 20:01:07 【问题描述】:

这是我用 QtCreator 制作的一个非常简单的 C++ 应用程序:

int main(int argc, char *argv[])

    int a = 1;
    int b = 2;

    if (a < 1 or b > 3)
    
       return 1;
    
    return 0;

对我来说,这不是有效的 C++,因为关键字 or 不是保留关键字。

但是如果我编译并运行它,它可以正常工作,没有任何警告!退出代码为 0,如果我更改 b = 4,退出代码为 1!

我没有包括任何东西来确保没有隐藏的定义。

这对我来说真的很奇怪。这是 Qt 定义的东西吗?我在文档中没有找到任何相关内容。

【问题讨论】:

什么意思?或 C++ 中的关键字。 @MichaelFoukarakis 我认为 well spotted 表示问题的 why does this code compile? 部分:有些编译器需要 #include &lt;iso646.h&gt; 而有些则不需要。大多数(如果不是全部)IDE 不会突出显示这些新的“关键字”。 【参考方案1】:

根据Wikipedia:

C++ 定义关键字作为别名 对于许多起作用的符号 作为运算符:and (&&)、bitand (&)、 and_eq (&=), or (||), bitor (|), or_eq (|=), xor (^), xor_eq (^=), not (!), not_eq (!=), compl (~)。

作为MadKeithV points out,这些替换来自C 的iso646.h,并作为运算符关键字包含在ISO C++ 中。 iso646.h 的***文章说,这些关键字的原因确实是国际键盘和其他可能无法轻松访问符号的非 QWERTY 键盘。

【讨论】:

酷 - 自 90 年代初以来我一直在编写 C++,但我对此一无所知。我不太可能使用它,但很高兴知道。 我也不知道,直到我看了。使用起来似乎很尴尬,而且我敢肯定有很多人编写 C++ 却不了解它。 我相信添加这些是为了帮助那些使用非英语键盘的人,这些键盘可能没有所有的符号键(&、| 等)。 +1。 IRC 上的一些人有一天会这样做:struct y compl y(); ; :) 实际上我最近开始在某些地方使用 (在 C++ 程序中包含 iso646.h 的正确方法),尤其是单元测试。例如:if (!someCondition) 在我看来比if (not someCondition) 好得多,因为有时一目了然!在括号旁边迷路了。【参考方案2】:

or 是 C++ 关键字,您可以使用它来代替 ||。没有魔法。

and 和大多数其他逻辑运算符也是如此。不过,通常最好坚持使用众所周知的名称,以避免这样的混淆。如果你使用or,有人会想“为什么会这样编译”;)

【讨论】:

旧答案,我知道,但我只想冷静和迂腐指出它们不是关键字,而是替代标记。男孩,我觉得挑剔和烦人很酷。 讽刺> 哦,对了,我没有意识到这种区别。但是,是的,看起来你是对的。 :) @GManNickG:它们是关键字(至少在当前的工作草案中):第 C.5.2.3 节:“tokens and, and_eq, bitand, bitor, compl, not_eq, not, or, or_eq、xor 和 xor_eq 是本国际标准 (2.11) 中的关键字。它们不显示为 中定义的宏名称。"【参考方案3】:

iso646.h 定义了许多运算符替代项 - 它是 C++ 标准的一部分。

【讨论】:

&lt;iso646.h&gt; 在 C++ 中为空。 它不在 Visual Studio 2003 到 2010 中 (msdn.microsoft.com/en-us/library/bw6140c5%28VS.80%29.aspx) 让我改写一下:就 C++ 编译器而言,该文件是空的。检查源代码,您会看到宏以未定义 __cplusplus 宏为条件。 除非定义了_MSC_EXTENSIONS MSVC 没有实现自 1989 年 C 标准以来添加的大量内容。 是作为 1994 年更改的一部分添加的,以及各种宽字符标题等。

以上是关于关于C++的一个问题,为啥下面这段代码如果不申请空间就成功不了呢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这段代码会给出“可能的空引用返回”编译器警告?

或者是无效的 C++:为啥这段代码会编译?

C++ 无法理解为啥这段代码不是线程安全的

为啥下面我写的这段代码老是提示"不允许使用不完整类型"

为啥这段代码不能在 Visual Studio 2010 中编译和运行?

为啥打字稿允许我覆盖一个空的状态对象?