提问人:johan boscher 提问时间:6/28/2020 最后编辑:johan boscher 更新时间:6/29/2020 访问量:1334
C++ 中带有 cout 的指针
Pointers with cout in C++
问:
我正在学习 C++ 和 SDL,当我尝试打印数组的内容时,我遇到了一些困惑。我有一个数组,其中包含两个值,2 和 3。当我想打印这样的值时:
int* test = myApp.countDivisions(5);
std::cout << "Horizontal: " << *test<< std::endl;
std::cout << "Vertical: " << *(test+1) << std::endl;
我得到:
Horizontal: -858993460
Vertical: -858993460
但是当我写的时候:
int* test = countDivisions(5);
int foo = *(test);
int boo = *(test+1);
std::cout << "Horizontal: " << foo << std::endl;
std::cout << "Vertical: " << boo << std::endl;
我得到:
Horizontal: 2
Vertical: 3
我很困惑为什么会这样。如果有人能解释为什么会发生这种行为,那就太好了!我知道我不应该在 C++ 中使用 C 数组,但我仍然有兴趣了解这里发生了什么!
编辑:我在第一个示例中修改了一个错别字。 我还被问到我的 countDivisions(int) 函数是做什么的,所以这里是整个代码:
#include <iostream>
#include <SDL.h>
class SDLApplication {
private:
//This is the window of the application:
SDL_Window* AppWindow;
//This is the surface displayed by the window:
SDL_Surface* WindowSurface;
SDL_Renderer* Renderer;
//This is the name of the App:
std::string AppName;
//These are the dimensions of the window displaying the App
int WindowWidth;
int WindowHeight;
public:
SDLApplication(std::string name) {
AppWindow = NULL;
WindowSurface = NULL;
AppName = name;
WindowHeight = 0;
WindowWidth = 0;
Renderer = NULL;
}
int* countDivisions(int divisions) {
//This helper functions takes as input the number of divisions on the screen and returns an array that tells
//us how many horizontal and vertical divisions we have, assuming we divide linearly starting from the right corner.
int horizontal = 0;
int vertical = 0;
int i = 0;
int divTemp = pow(2,i);
int divCount = divTemp;
int temp;
while (divCount < divisions) {
if (i % 2 == 0) {
//Our power of two is pair, so we are adding horizontal divisions
horizontal += divTemp;
}
else {
//Our power of two is odd, so we are adding vertical divisions
vertical += divTemp;
}
++i;
divTemp = pow(2,i);
temp = divCount + divTemp;
if ( temp> divisions) {
if (i % 2 == 0) {
//Our power of two is pair, so we are adding horizontal divisions
horizontal += divisions-divCount;
}
else {
//Our power of two is odd, so we are adding vertical divisions
vertical += divisions-divCount;
}
}
divCount =temp;
}
int result[] = { horizontal, vertical };
return result;
}
}
int main(int argc, char* argv[])
{
SDLApplication myApp("SDL_Test");
int* test = myApp.countDivisions(5);
std::cout << "Horizontal: " << *test << std::endl;
std::cout << "Vertical: " << *(test + 1) << std::endl;
return 0;
}
答:
我认为印刷是一种未定义的行为——它有点毫无意义。此表达式是一种类型。这有点像说“人类在哪里”而不是“人类叫鲍勃在哪里”(好吧,有点垃圾类比),一个类型本身没有地址。*int
第二个示例是一个名为 test 的变量,其类型为 (指向整数的指针)。你设置指向某物的指针的值(无论 myApp.countDivisions(5) 是什么;返回 - 你应该告诉我们它返回什么)。int* test
int*
test
然后:
int foo = *(test);
int boo = *(test+1);
foo 是一个整数变量,您可以将其设置为测试指向的值,而不是地址本身。 设置为下一个地址(测试地址 + 1)的内容。boo
如果要打印指针的地址,则应执行以下操作:
std::cout << "Horizontal: " << test << std::endl;
如果要打印指针指向的值,则应执行以下操作:
std::cout << "Horizontal: " << *test << std::endl;
这称为取消引用。请看这个小例子:https://godbolt.org/z/CzHbq6
更新:根据问题更新进行更新
您正在返回指向名为 的局部变量的指针。该变量在 countDevisions() 函数的末尾被销毁,这将导致未定义的行为(您正在看到),这意味着任何事情都可能发生!有关打印出警告的示例,请参阅此处:https://godbolt.org/z/gW2XS4result
对此的“一个”解决方法是通过使其生命周期成为程序的整个生命周期来更改范围,这可以通过使其 .请注意,我这样做只是为了演示 - 这不是一个好的解决方案,但在这里看到它的工作:https://godbolt.org/z/goQJzxresult
static
也许更好的解决方案是从标准模板库 (STL) 返回一个容器,例如 std::vector(类似于数组):https://godbolt.org/z/3DOyhq
或者(在正确阅读代码后)您甚至不需要数组,似乎您只需要两个值:垂直和水平。因此,您可以定义自己的结构并使用它 - 这似乎更理想:https://godbolt.org/z/RmUM39。这对函数的用户来说也更有意义,因为它能够按名称而不是某些数组索引引用水平/垂直。
评论
std::cout << "Horizontal: " << *test << std::endl;
TLDR:“打开警告”并搜索“c++ return multiple values”
您需要包含 iostream 并定义三个类,并修复另外两个拼写错误。
#include <iostream>
typedef int SDL_Window;
typedef int SDL_Surface;
typedef int SDL_Renderer;
这将导致代码提供有用的警告消息,告诉您 SDLApplication::countDivisions 返回局部变量或临时变量的地址。当您稍后尝试使用超出范围的临时对象时,结果(毫不奇怪)是未定义的行为。
函数返回多个值。你可以创建一个 std::tuple 对象,但我只定义一个结构,这样你就可以返回一个值,并带有命名成员。
struct Divisions {
int horizontal;
int vertical;
};
class SDLApplication {
...
Divisions countDivisions(int divisions) {
...
return Divisions{ horizontal, vertical };
}
};
另
请参阅 将多个值返回给方法调用方
从 C++ 函数返回多个值
评论
*int
*(int+1)
myApp.countDivisions(5);
std::vector
countDivisions