因此,我正在阅读learningcpp教程,并且试图打印char指针的地址,因为当您这样做时:
char c{'i'};
cout << &c << endl;
它只会打印字符串“ i”,因为我猜编译器会确定一个指向字符串char数组的char指针(但是我不明白为什么它只是打印“ i”,因为没有字符“ i”后的“ \ 0”)。
无论如何,然后我尝试将char指针static_cast转换为一个int指针,这样它将打印出地址:
char c{'i'};
cout << static_cast<int*>(&c) << endl;
但是这甚至没有编译,我遇到一个错误“无效的static_cast从类型<< char * >>到类型<< int * >>”。
最后,我只是尝试了这样的C型演员:
char c{'i'};
cout << (int*)(&c) << endl;
它起作用了,它会打印一个地址。
所以我的问题是:
谢谢
答案 0 :(得分:4)
首先,static_cast<int*>(&c)
将失败,因为static_cast
仅允许非常具体的类型转换子集。例如,您可以static_cast
在数字类型之间,或在两个通过继承关联的类类型之间(即,一种在继承层次结构中的某个点继承另一种)。
您正在做的只是简单地尝试将地址“重新解释”为其他类型的地址。原因是C ++ std::ostream
对于operator<<
重载了const char*
。如果只想打印地址本身,则标准约定是通过void*
转换为static_cast<void*>(&c)
或仅在(void*)&c
转换为C样式转换的情况下转换为void*
。 const_cast
基本上是一个没有类型信息的指针,如果您只想打印出地址本身的值,那么这很完美。
之所以编译C风格的案例是因为C风格的强制转换使用了非常……应该说是冒险的方法来执行转换。为了执行您指定的转换,可以执行reinterpret_cast
,static_cast
和char*
(必要时)。此行为在cppreference.com上有详细说明。
关于为何打印data
的示例尽管未终止也直接仅打印单个字符的原因:未定义的行为是未定义的。显然,恰好发生了(使用此编译器)可执行文件紧随其后的零(空)字节,无论它在哪里。编译器甚至可能意识到您分配了一个值,但从未修改过,因此它甚至可能不在堆栈中(它可能在可执行文件的Platform
段中)。故事的寓意只是不要引起未定义的行为。
答案 1 :(得分:-2)
让我举个例子。打印地址与打印指针相同。如
from collections import Counter
def contains(container, contained):
" True if all values in dictionary container >= values in contained"
return all(container[x] >= contained[x] for x in contained)
def sublist(lst1, lst2):
" Detects if all elements in lst1 are in lst2 with at least as many count "
return contains(Counter(lst1), Counter(lst2), )
Tuple1 = (1,2,2)
TupleList = [(1,2,3), (1,2,3,2)]
# List of tuples from TupleList that contains Tuple1
result = [x for x in TupleList if sublist(x, Tuple1)]
print(result)
>>>[(1, 2, 3, 2)]
两者都一样。
现在对char使用类似的情况,看看会发生什么情况
Int* a;
cout<<a;// print the address Lets look another
Int a;
cout<<&a; // print the address, after casting into int*
所以这就是为什么char a = 'a'
cout<<&a; // it is printing value of *a means char* a
打印char而不是address的原因,因为在转换后打印&a
的地址,char
成为char
,它是数据类型为char*
指针。