我正在自学C++,因此一直在编写一些示例代码来真正指出我对指针和数组的理解.
我写了这个:
int myints[] = {20, 40, 60, 80, 100}; // C style array? should be stored on stack? is myint's type pointer to int or an array of int? how does it differ from myotherints? int* myotherints = new int[5]{20, 40, 60, 80, 100}; // new always returns pointer, is this a C++ style array? // does this pointer get created on stack while the elements themselves are created in free heap? int j = 5; // should be stored on stack cout << "myints: " << myints << endl; // decays to pointer, shows address array myints is stored at cout << "*myints: " << *myints << endl; // myints decays to pointer and is dereferenced to return value stored at start of array myints cout << "myints[0]: " << myints[0] << endl; // [] dereferences and returns value for element 0 (20) cout << "myotherints: " << myotherints << endl; // some value?? this is totally unlike the others, why? what is this? cout << "*myotherints: " << *myotherints << endl; // dereferences pointer myotherints to get address that holds value 20 for first element cout << "myotherints[0]: " << myotherints[0] << endl; // [] dereferences pointer to get address that holds value 20 for first element cout << "j: " << j << endl << endl; // 5, sure cout << "&myints: " << &myints << endl; // array behaving as pointer, gives address of myints[0] cout << "&myints[0]: " << &myints[0] << endl; // array behaving as pointer, gives address of myints[0] cout << "&myotherints: " << &myotherints << endl; // address of myotherints, is this where the pointer to the array is stored? cout << "&myotherints[0]: " << &myotherints[0] << endl; // [] dereferences the pointer that myotherints points to and returns element 0 cout << "&j: " << &j << endl; // address of j /* myints: 0x7fff096df830 <-- this makes sense to me, array decays to pointer to give first element address *myints: 20 <-- this makes sense to me, dereference first element address for value myints[0]: 20 <-- [] dereferences implicitly, returns value from pointer myotherints: 0x2308010 <-- myotherints is a pointer to an array of ints, but its address is much lower compared to myints and j, why is that? *myotherints: 20 <-- getting the value from above address returns 20 myotherints[0]: 20 <-- [] dereferences to address pointed to by pointer myotherints, returns value j: 5 &myints: 0x7fff096df830 <-- same as below &myints[0]: 0x7fff096df830 <-- same as above, meaning *myints and myints[0] are the same thing, this address &myotherints: 0x7fff096df828 <-- how can the pointer to myotherints array be stored here when dereferencing it (*) returns 20 and... &myotherints[0]: 0x2308010 <-- dereferencing this address with [] also returns 20, yet they are different memory locations unlike myints &j: 0x7fff096df824 */
是不是说myint是一个"C风格数组",而myotherints是一个"C++风格数组"?
如果我理解正确,myotherints是一个指针但myints是一个数组,大多数时候表现得像一个指针?因此,虽然您可以使用myint进行指针处理,但有时候它不像指针那样,即使用&来显示其地址.这意味着myints与指针的类型不同.它的类型是"一系列的整数"吗?
存储myint(myins的东西,而不是其数组中的值),如果它总是自动解除引用数组存储的位置,我怎么能显示它的地址?与使用C++样式的新数组返回的指针不同?
这些在功能上以不同的方式表现在记忆中吗?
任何能够真正巩固我理解的文档提示或指示都将非常感激.谢谢!
C++从C语言中获得了类型衰减
在C中,有几种方法可以有效地使用整个数组.你不能把它们传递给函数,从函数返回它们,执行[]
或==
或者+
他们至少直接或几乎所有的东西.
相反,每当你看到它有趣时,数组'衰变'到指向它的第一个元素的指针.(基本上,每当你在除了被视为实际数组的少数情况下使用它之外,它会衰减成指针).
所以arr[3]
变成(&(first element of arr))[3]
或*((&(first element of arr))+3)
(这些意思是相同的).
当您return arr;
将其传递给函数(在C中)时会发生类似的事情.你的cout << arr
手段cout.operator<<( arr )
,这只是一个功能.好吧,它也可能operator<<( cout, arr )
.在C++中,您可以将对实际数组的引用传递给函数,但它需要一些工作并且不会在您的示例代码中发生.
如果你输入&arr
decay没有发生,你得到一个指向整个数组的指针.这很重要,因为指针算法,以及其他原因,以及数组数组如何以零开销工作. (&arr)+1
指向数组的过去,不管它有多大 - ((&(arr[0]))+1)
指向数组的第二个元素.
这是int arr[3]={4,5,6};
有效的,或者int arr[]={4,5,6};
(同样的 - 第二个只是3
为你决定数字). arr
在这两种情况下都是类型int[3]
.它int*
容易衰变,但它是类型的int[3]
. sizeof(arr)
是三倍sizeof(int)
,而不是sizeof(int*)
.
当你new int[3]
,你没有得到一个指针int[3]
,而是你得到一个指针int[3]
数组的第一个元素.从某种意义上说,它会被预先腐烂.这是指针的类型 - 数组的地址和第一个元素是相同的.但是类型信息(这是一个组合时间概念)不同!
它也存储在免费存储中,而不是自动存储(也就是堆和堆栈).但这不是根本区别.
C++唯一关于new int[3]
你的东西new
- 你可以malloc
用来获取免费商店的数据空间,并获得一个指向第一个元素的指针int*
.
两者都是从C继承的东西(正确的C++数组的东西是std::array
),但是你很困惑:
第一个是C数组,即具有静态/自动存储持续时间的事物,代表一块内存.该块的大小和"位置"(地址)在编译时确定.
第二个是一个指针到一个动态分配的内存块.换句话说,您使用指针将您请求的内存块的地址存储到OS.这对新手来说很困惑,因为这个东西有时被称为动态数组.C阵列不是一个相同意义上的数组,但实际上我们以相同的方式使用它们,但出于不同的目的.
关于C++:
C数组的行为类似于内存块的指针和一些含糖(数组索引等),因此它们总是通过引用传递(因为我们拥有的是通过值传递的地址,而不是数组本身),实际上它们会自动衰减在许多情况下指向.这些问题是std::array
一个更好的选择,因为它具有正确的值语义并且没有隐式衰减.
在C++手册中应该避免内存管理,你应该使用标准库提供的容器(最着名的std::vector
).C++语言提供自动,确定性和安全资源管理的功能; 包括内存资源.你应该使用这些.手动内存管理仅适用于非常低级别的编程和创建自己的资源管理处理程序.