我对指针/引用中C++"&"运算符的不一致应用感到困惑?
I'm confused by the inconsistent application of the "&" operator in C++ in pointers/references?
我已经检查了许多编程语言(Java,Erlang,python等(但我发现 C/C++ 集会很难学。仅仅因为我认为它有时不合理;
例1:
#include <iostream>
int main() {
int ar1 = {1,2,3};
int *p1 = ar1;
char *msg = "message";
std::cout << "addr: " << p1 << std::endl ;//prints the array address
std::cout << "value: " << *p1 << std::endl ;//prints the first element
std::cout << "addr: " << msg << std::endl ;//prints "message" , wtf why not the addr?how can i get its address?
std::cout << "value: " << *msg << std::endl ;//prints the first character
}
例2:
#include <iostream>
int main() {
int n1 = 5;
int *p1 = &n1;
int &r1 = *p1; // why not: int &r1 = p1; ,*p1 is NOT an address,p1 is.This does not make any sense...
}
你能给我解释一下这些例子吗?如果不解决这些问题,我就不能继续研究Cplusplus。
谢谢你的时间。
问题 1:
char *msg = "message";
std::cout << "addr: " << msg << std::endl ;
//prints "message" , wtf why not the addr?
这是该语言从 C 开始的历史演变的人工制品,其中字符串通常由字符数组或指向此类数组的指针表示。为了支持这一点,<<
有一个重载char const *
,它将其视为指向字符串的指针并打印字符串内容。
可以通过使用 std::string
类来表示字符串来避免混淆,并避免使用 C 样式字符串,除非在(非常罕见的(情况下它们很有用。
how can i get its address?
您可以将其转换为通用指针:
std::cout << "addr: " << static_cast<void*>(msg) << std::endl;
^^^^^^^^^^^^^^^^^^
问题2:
int n1 = 5;
int p1 = &n1;
这不会编译,因为&n1
是一个地址,因此只能用于初始化指针,而不是int
。我假设你的意思是:
int *p1 = &n1;
int &r1 = *p1;
// why not: int &r1 = p1; ,*p1 is NOT an address,p1 is.This does not make any sense...
因为引用不是指针,并且不使用地址初始化。引用必须使用(有效(对象初始化,并成为该对象的别名。 *p1
是一个类型为 int
的对象,因此可以用来初始化对int
的引用。
&
符号可能会让C++中的新人感到困惑。这是因为&
可以有多种含义。
这:
int* p1 = &n1;
表示获取 n1 的地址并将其存储在指向 int 的指针中。 p1
是一个指针,保存n1
的地址。
这:
int &r1 = *p1;
表示创建称为引用的特殊类型的变量。(在C++引用实际上只是其他东西的别名(。R1 被告知在 *p1
处为值指定别名。 *p1
表示跟随指针 p1 并获取基础值。在这种情况下,我们知道p1
指向n1
因此我们在这里知道r1
是对n1
的引用。意思是如果我这样做:
r1 = 5;
然后
std::cout << n1;
输出将是5
也可以表示二进制和运算符。这是你在这里不问的完全不同的事情。
问题的很大一部分是你的例子大多是错误的。
第一个例子:
int ar1 = {1,2,3};
int *p1 = ar1;
为了正确起见,这需要;
int ar1[] = {1, 2, 3};
int *p1 = ar1;
在这种情况下,事情非常简单:在大多数情况下(包括这种情况(,数组的名称计算为该数组开头的地址(即,您分配给指针的值类型(。主要的例外是当您使用数组作为sizeof
运算符的操作数时,因此sizeof(ar1)
会给出数组的实际大小(3 *sizeof(int)
(,而不是指针的大小。
在第二个示例中:
int n1 = 5;
int p1 = &n1;
int &r1 = *p1; // why not: int &r1 = p1; ,*p1 is NOT an address,p1 is.This does not make any sense...
你是对的 - 这没有任何意义,正常运行的编译器不应该按原样编译它。你显然想要的是这样的东西:
int n1 = 5;
int *p1 = &n1; // p1 is a pointer to int, holding address of n1
int &r1 = *p1; // r1 is a reference to int, referring to what p1 points at (n1).
就打印内容而言,这很简单:任何类型如何打印出来纯粹是由编写库的人做出的决定。他们认为,当您将指针传递给 char 时,它会假设您想要打印指向的字符串,这是最有意义的。对于其他指针类型,他们决定打印出指针本身的值。不过,这些都不是关于语言本身的——这只是某人做出的决定,因为这对他们来说是有意义的。
如果你有一个指向 char 的char/指针数组,并且想要打印出地址而不是它指向的字符,你通常将其强制转换为指向 void 的指针:
char *msg = "message";
std::cout << static_cast<void *>(msg);
至于他们为什么选择这个,我认为很简单:因为当人们说cout << mystring
时,他们通常希望将字符串的内容打印出来。这通常仅限于字符串,因为(几乎(每个人都同意如何打印出字符串的内容,但在涉及 int、double 等数组的内容时就不那么多了。
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- void 函数中的指针参数返回不一致的值
- 如何查找导致结果不一致的代码
- 跨平台 mySQL 与字符集不一致
- C++:不一致的 std::p ow( 类型 ) 定义
- 我对指针/引用中C++"&"运算符的不一致应用感到困惑?