为什么我们允许运行此代码:
int* FunctionB(int x)
{
int temp =30;
//more code
return &temp;
}
在我看来,我没有回复我说的话。如果我将返回类型声明为指针,为什么可以返回内存地址。指针不是指向内存地址的东西,实际上不是内存地址吗?
class Image : public BMP
{
public:
void invertcolors();
void flipleft();
void adjustbrightness(int r,int g,int b);
private:
};
编译完前面的代码后,我收到了这个错误:
image.h:3: error: expected class-name before ‘{’ token
但我认为我使用正确的语法来声明子类。我写的东西有问题吗?
答案 0 :(得分:4)
在第一种情况下,指针是一个内存地址,指向某些数据,因此您的语法是正确的。但是,在这种情况下,您将返回局部变量的地址,因此未定义函数调用结束后它将指向的内容。
在第二种情况下,编译器抱怨,因为它不知道BMP
是什么。您可能忘记了#include
类的BMP
标题文件。
答案 1 :(得分:4)
就你的第一个问题而言
为什么我们允许运行此代码:
没有什么可以阻止你返回局部变量的地址但是危险(标记我的话)。 Infact返回地址或局部变量的引用调用 Undefined Behavior (这意味着任何事情都可能发生)。
另请查看this.
如果我将返回类型声明为指针,为什么可以返回内存地址?
这意味着你必须学习指针的基础知识。在计算机科学中,pointer是一种编程语言数据类型,其值直接指向(或“指向”)存储在计算机内存中其他位置的另一个值,使用其地址。
..但我以为我使用正确的语法来声明一个子类。我写的东西有问题吗?
您是否定义了BMP或者是否包含了包含其定义的标题?
答案 2 :(得分:4)
在C和C ++语言中,术语地址和术语指针是[几乎]精确的同义词。在实际的,不太正式的语言中,术语地址大部分用于指代 rvalue 指针值,而术语指针可用于 rvalue 和 lvalue 指针值。在第一个示例中,您将返回一个右值,因此术语“地址”和“指针”可以互换使用。您正在将指针返回到int
对象。您正在返回int
对象的地址。两者都意味着同样的事情。当然,除了故意尝试导致未定义的行为之外,返回本地对象的地址是没有意义的。
至于第二个问题,编译器根本不知道BMP
是什么。你没有宣布它。此外,必须先定义一个类,然后才能将它作为另一个类声明的基础。
答案 3 :(得分:0)
以这种方式思考:
如果
char myChar;
声明一个存储字符的变量
int* myPtr;
声明一个存储内存地址的变量。
类似地,如果
char myCharFunction();
声明一个返回一个字符的函数,
int* myPtrFunction();
声明一个返回内存地址的函数。
因此,由于函数的签名是int* FunctionB(int x)
,因此返回内存地址是正确的。
这里要理解的重要一点是int*
表示“内存地址”。而我们称之为“指针”的只不过是一个变量,它将内存存储为一个地址。当有人说指针“指向一个地址”时,他们的意思是指针本身就拥有该地址(就像一个char
变量会保存一个字符)。