我有下面两行代码。
const char* skimfile = argv[3];
cout << "skimfile = " << skimfile << endl;
我知道上面两行代码是有效的 但我不知道为什么。如果我们要打印出指针所指向的值,是不是应该用 *skimfile
? 为什么上面的代码只用了 skimfile
来访问指针指向的值。skimfile
? 是否有 const
在指针的声明前面,使这种情况有所不同?
非常感谢您的帮助! 我真的很感激!
如果你想输出指针的值,那么就写上
cout << "skimfile = " << static_cast<void *>( skimfile ) << endl;
否则,字符指针的操作符<<就会被重载,从而输出一个指向的字符串。
如果没有这样的重载操作符,你就必须写出这样的代码,例如
const char *s = "Hello";
for ( const char *p = s; *p; ++p )
{
std::cout << *p;
}
std::cout << '\n';
而不是仅仅
std::cout << s << '\n';
不,这不是因为 const
. 这正是它应该工作的方式,这就是为什么。
skimfile是一个指针(在本例中它是一个指向const char的指针)--所以*skimfile是指针指向的对象。
所以cout << *skimfile应该只打印第一个字符。
当你这样做的时候 - cout << skimfile - 你传递的是指针本身。而cin会把整个字符串打印出来,换句话说,它会做cout <<skimfile。换句话说,它会执行cout << *skimfile,然后执行cout << *(skimfile+1),直到它走完整个字符串。
如果你想打印地址,你必须把它投射到其他类型的指针上--cout << "skimfile = " << (void*)skimfile << endl;
这里有一个更详细的答案。
std::ostream如std::cout只是一个二进制函数。operator<<
.
对于大多数指针,回退只是打印它的地址。
但是 char const*
打印的是一个C型字符串或C型字符串文字。 ostream& operator<<(ostream&, char const*);
打印字符,直到有一个 '\0'
停止循环。
你可以用一些简单的结构来模拟这种行为。
#include <iostream>
using std::cout;
using std::ostream;
namespace {
struct Coord { int x; int y; };
struct Stuff { int x; int y; };
ostream& operator<<(ostream& out, Coord const& coord) {
out << coord.x << ", " << coord.y;
return out;
}
ostream& operator<<(ostream& out, Coord const* p) {
out << p->x << ", " << p->y;
return out;
}
ostream& operator<<(ostream& out, Stuff const& stuff) {
out << stuff.x << ", " << stuff.y;
return out;
}
} // anon
int main() {
auto coord = Coord{10, 20};
auto stuff = Stuff{30, 40};
auto pcoord = &coord;
auto pstuff = &stuff;
cout << "Coord: " << coord << "\n";
cout << "PCoord: " << pcoord << "\n";
cout << "Stuff: " << stuff << "\n";
cout << "PStuff: " << pstuff << "\n";
}
它的输出是:
Coord: 10, 20
PCoord: 10, 20
Stuff: 30, 40
PStuff: 0x7ffeeaa06a88
这里的重点是,你要打印的是 char*
变量。
如你所知,在你的代码中 skimfile
是指向一串字符的第一个字符。所以当你要打印它时,它会继续从内存中读取,直到得到 NULL
值,因此,它将打印所有的字符串字符,而不是其地址。