从我所见,指针符号和数组符号有很大的重叠。每种符号方法的独特之处是什么?在什么情况下使用一种方法比另一种方法更有益?
int main(){
int arr[]={1,2,3,4};
int * arrPtr = arr;
for (int i = 0; i < 4; ++i){
cout<<arr[i]<<" "<<arrPtr[i]<<" "<<*(arr+i)<<" "<<*(arrPtr+i)<<endl;
}
return 0;
}
答案 0 :(得分:1)
T [N]类型的对象知道编译时N是什么。 T *的对象不知道目标地址有多少T。
此代码:
#include <iostream>
int main()
{
int a[10];
int* b = new int[10];
std::cout << sizeof(a) << ", " << sizeof(b) << "\n";
}
输出40, 4
(http://ideone.com/GANFtB)。
数组衰减指向指针(参见http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr),以便在编写时
void f(int a[])
你实际上正在使用原型
创建一个函数void f(int a*)
此时,您不再知道a
的维度。
但是,指针和数组旨在相互补充。当你有
int a[4] = { 1, 2, 3, 4 };
a
很乐意为你指出一个指针
int a[4] = { 1, 2, 3, 4 };
int *p = a;
std::cout << a[0] << p[0] << *a << *p << *(a+1) << *(p+1);
将打印111122
(http://ideone.com/G61NL1)
使用固定大小的数组意味着: - 作为局部变量,它将在堆栈中。优点:速度,局部性,缺点:大小受到限制,大小必须在编译时知道。 - 作为全局变量:程序二进制文件中的固定大小分配,编译时需要的大小。 - 作为成员变量:将对象大小增加一个已知数量,编译时所需的大小。
指针允许您分配动态内存,但需要传递大小参数:
void f(int* a, size_t elements);
使用数组,您可以使用技巧编写特定于大小的代码:
void f(int (*a)[10]); // require input to be an array of 10 elements
int a[4];
f(&a); // error: int (*)[4] can't convert to int (*)[10]
和模板技巧:
template<size_t N>
void dump(int (&a)[N]) // takes arrays with known size only
{
std::cout << "[" << a[0];
for (size_t i = 1; i < N; ++i)
std::cout << ',' << a[i];
std::cout << "]";
}
int main() {
int a[] = { 1, 2, 3, 4 }; // compiler calculates size
dump(a);
}
所有这一切都说,语言都没有实现边界检查:
int main() {
int a[10];
a[100] = 1; // compiles and links
}
如果您使用std::array
和at
运算符,则可以获得经过边界检查的数组访问权限。
std::array a<int, 4>;
a.at(20); // detected as runtime error and not UB
答案 1 :(得分:0)
在什么情况下使用一种方法比另一种方法更有益?
实际上并没有什么区别,所以我们无法判断使用其中一个是否有任何优势。
而是使用std::vector<int>
或std::array<int,4>
关于c ++。
答案 2 :(得分:-1)
int arr[]
vs int * arrPtr
int arr[]
和int * arrPtr
之间的区别在于编译器&#34;知道&#34;一个是数组,另一个是指针;)
例如:
int arr[] = { 1, 2, 3, 4 };
int * arrPtr = arr;
cout << "sizeof(arr): " << sizeof(arr) << endl
<< "sizeof(arr[0]): " << sizeof(arr[0]) << endl
<< "sizeof(arrPtr): " << sizeof(arrPtr) << endl
<< "sizeof(arrPtr[0]): " << sizeof(arrPtr[0]) << endl;
可能会打印如下内容:
sizeof(arr): 16
sizeof(arr[0]): 4
sizeof(arrPtr): 8
sizeof(arrPtr[0]): 4
arr[0]
和arrPtr[0]
是相同的,但arr
和arrPtr
不是。你可以使用这个事实。
Arrays还为编译器提供了进行边界检查的机会,但这是有限的。
静态检查至少可以在某些编译器上运行。例如。这不能在VCC中编译:
int arr[] = { 1, 2, 3, 4 };
arr[4] = 7;
但是没有办法对此提出保护:
arr[x] = 7;
还有一些函数可以根据数组大小实现运行时保护。例如,这不会在s1
:
char s1[] = "aaa";
sprintf_s(s1, "sssssssssssssssssss");
失败了,因为sprintf_s
&#34;知道&#34;大小s1
(大小实际上是sprintf_s的模板参数)。
arr[i]
vs *(arr + i)
对于整数数组,arr[i]
和*(arr + i)
之间没有区别。但是对于你自己的指针式类,你可以覆盖[]
和+
运算符,使它们与众不同。