这是来自OOP高级课程考试的问题,用C++教授(在TAU大学,本学期):
问:C++指针和引用有什么区别?
A. A reference is the entire object while a pointer is only the address of it. B. The same meaning, and difference is only in syntax and usage. C. The syntax used to access the object. D. Pointers are simple address to the object while a reference uses the virtual table.
哪个是正确的答案?
课程老师声称A是正确的,并且对象的引用实际上是对象本身.那是对的吗?我意识到访问引用等同于访问对象本身,但是,在破坏引用时,我们不会破坏对象本身.引用是对象的替代名称,但是说reference == object true?
顺便说一句,讲师给了一个faq的以下链接作为对他的主张的支持,引用:
"重要提示:尽管引用通常是使用底层汇编语言中的地址实现的,但请不要将引用视为指向对象的滑稽指针.引用是对象.它不是指向对象的指针,也不是对象的副本.这是对象."
但是,我认为这是不正确的.
我一直在阅读 C++ Primer 第 5 版。它提到
将 int 变量分配给指针是非法的,即使该变量的值恰好为 0。
我试了一下,结果如下:
int *u = 0; // success
int *w = 123; // fail
/* compile error:
ptr_test.cc:9:12: error: invalid conversion from 'int' to 'int*' [-fpermissive]
int *w = 123;
*/
int zero = 0;
int *v = zero; // fail
/* compile error
ptr_test.cc:9:12: error: invalid conversion from 'int' to 'int*' [-fpermissive]
int *w = zero;
*/
Run Code Online (Sandbox Code Playgroud)
有人可以帮我解释一下指针初始化的确切规则吗?为什么将 int 指针分配给 0 可以,但 123 不行,尽管它们都是整数?为什么 123 会导致转换为“*int”,而 0 不会?
顺便说一句,我使用的是 g++ …
我注意到*(*int)(nil) = 0函数中有一行throw
//go:nosplit
func throw(s string) {
// Everything throw does should be recursively nosplit so it
// can be called even when it's unsafe to grow the stack.
systemstack(func() {
print("fatal error: ", s, "\n")
})
gp := getg()
if gp.m.throwing == 0 {
gp.m.throwing = 1
}
fatalthrow()
*(*int)(nil) = 0 // not reached
}
Run Code Online (Sandbox Code Playgroud)
是什么*(*int)(nil) = 0意思?既然这条线*(*int)(nil) = 0无法到达,为什么它在这里?有什么特殊用法吗?
非常简单的代码:
void *allocateMemory5DArray(size_t x, size_t y, size_t z, size_t q, size_t r)
{
int (*array)[x][y][z][q][r];
array = malloc(sizeof(*array));
return array;
}
Run Code Online (Sandbox Code Playgroud)
-O0gcc需要 296 字节的堆栈,生成的代码长度 > 180 行。任何人都可以解释其背后的原理吗?
其他编译器(除了 clang)也会生成奇怪的代码,但不像gcc:)
我正在阅读 Bjarne Stroustrup 的《C++ 编程原理与实践》(第二版)。在第 660-661 页,作者定义了一个函数,如下所示:
istream& read_word(istream& is, char* buffer, int max)
// read at most max-1 characters from is into buffer
{
is.width(max); // read at most max-1 characters in the next >>
is >> buffer; // read whitespace-terminated word,
// add zero after the last character read into buffer
return is;
}
Run Code Online (Sandbox Code Playgroud)
稍后int main(),该函数被调用为read_word(cin,s,max);where cinis std::cin, maxis an int, and sis a chararray of size max …
可以定义指向成员的指针,并在以后使用它:
struct foo
{
int a;
int b[2];
};
int main()
{
foo bar;
int foo::* aptr=&foo::a;
bar.a=1;
std::cout << bar.*aptr << std::endl;
}
现在我需要一个指向数组特定元素的指针,所以通常我会写.
int foo::* bptr=&(foo::b[0]);
但是,编译器只是抱怨"invalid use of non-static data member 'foo::b'"是否可以这样做(或者至少没有工会)?
编辑:我需要一个指向数组特定元素的指针,因此int foo::* ptr指向数组的第二个元素(foo::b[1]).
还有另一个编辑:我需要访问数组中的元素bar.*ptr=2,因为指针在其他地方被使用,因此无法使用bar.*ptr[1]=2或调用它*ptr=2.
任何人都可以告诉我为什么这不会编译?
package main
type myint int
func set(a **myint) {
i := myint(5)
*a = &i
}
func main() {
var k *int
set( (**myint)(&k) ) // cannot convert &k (type **int) to type **myint
print( *k )
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的理由是这样的.Golang中的所有类型都不同,但只要底层类型相同,它就允许使用类似C的强制转换语法从一种类型转换为另一种类型.在我的例子中,将'int'转换为'myint'不是问题.'*int'到'*myint'也不是.当你有指向指针问题的指针出现时.我现在第二天一直坚持这个.任何帮助表示赞赏.
我有一个int指针数组,int* arr[MAX];我想将其地址存储在另一个变量中.如何定义指针数组的指针?即:
int* arr[MAX];
int (what here?) val = &arr;
Run Code Online (Sandbox Code Playgroud) 我觉得我错过了一些非常简单的东西,但我试图理解标记和扫描垃圾收集每个Andrew Appel的现代编译器实现在ML书中,并且Mark和Sweep部分中有一个标题为Pointer Reversal(270)的小段落.
在这一点上,我想我明白它是如何工作的.简而言之,当您遍历图形时,您可以翻转所有指针,以便您的前任位于您的字段集中.然后,当您完成给定元素后,将指针向后翻转,使它们再次指向正确的位置.
如果这是正确的,它究竟是什么给你买的?Appel试图解释这一点,但我并没有完全理解他的措辞.
如果我有以下代码:
int i = 5;
void * ptr = &i;
printf("%p", ptr);
Run Code Online (Sandbox Code Playgroud)
我会得到i或MSB的LSB地址吗?
平台之间的行为会有所不同吗?
C和C++之间有区别吗?