首先我猜想k1的值不会在主空间中。但后来我意识到数组是一个指针,所以有什么区别吗?我认为这是相同的,但也许任何人都可以找到一些其他的技术差异。也许更快地传递指针?
#include <iostream>
using namespace std;
void g(double [],int );
void f(double* [],int );
int main()
{
int n = 10;
double *k1, *k2;
k1 = new double[n];
k2 = new double[n];
g(k1,n);
f(&k2,n);
for(int i = 0;i <n;i++)
{
cout << k1[i]<< " ";
cout << k2[i] << endl;
}
delete [] k1;
delete [] k2;
return 0;
}
void g(double h[],int n)
{
for(int i = 0;i <n;i++)
h[i]=i;
}
void f(double* h[],int n)
{
for(int i = 0;i <n;i++)
(*h)[i]=i;
}
答案 0 :(得分:7)
首先,数组不是指针。这是10个双打的数组:
double a[10];
这是一个指向double的指针:
double *p;
这是一个指向10个双精度数组的指针:
double (*pa)[10];
这是一系列指向双打的指针:
double *pa[10];
当声明为函数参数时,数组和指针只是相同的。但是数组可以转换(衰减)成指向数组的第一个元素的指针:
double a[10];
double *p = a;
double *q = &a[0]; //same as p
在您的示例代码中:
double *x = new double[10];
您正在创建一个包含10个双打的动态数组,并获取指向该数组的第一个元素的指针。您还可以创建一个新数组并获取指向数组的指针:
double (*x)[10] = new double (*)[10];
但这种奇怪语法的表现很少有用。
关于函数,这是一个带有双精度数组的函数:
void g1(double h[], int n);
这是一个函数,它指向一个包含10个双精度数组的数组:
void g2(double (*h)[10]);
在指向数组的指针中,您需要指定数组的大小,因为您无法创建指向未知大小数组的指针。
这就是为什么数组实际上作为指针传递给函数的原因。但是指向数组的第一个成员的指针,而不是指向数组本身的指针。所以第一个函数实际上与这个函数相同:
void g1(double *h, int n);
由于您只将指针传递给数组的第一个成员(指向double的指针),因此您还需要在附加参数中指定数组的大小。优点是您可以传递任何大小的数组。甚至是阵列的拼接:
double x[20];
g1(x + 10, 5); //pass x[10..15]
关于哪一个更快,它们都是相同的,它们实际上是指向相同内存地址的指针。请注意,如果数组是结构的一部分,则只通过副本传递,并且结构按值传递。
我的建议是:如果你使用C棒到惯用的C,必要时使用指向数组第一个成员的指针,并尽可能避免使用指针到数组的语法。如果使用C ++,则使用容器,迭代器和范围。
答案 1 :(得分:3)
void f(double* h[],int n)
不接受指向数组的指针。你已声明它接受一个指针数组。
它工作的唯一原因是声明为数组的函数参数被静默地转换为指针,因此它等同于:
void f(double** h,int n)
这毕竟是你想要的。
这个(被g ++拒绝)代码将使用指向数组的指针:
void f(double (*h)[],int n)
答案 2 :(得分:2)
有了这个声明:
void f(double* [],int );
您说,作为第一个参数,您正在使用指向double
的指针数组。
当您使用(*h)
取消引用该参数(其被视为指向指针的指针)时,您实际上会获得该数组的第一个位置的地址。
答案 3 :(得分:1)
void g(double h[],int n);
在该功能中,您在技术上传递指针。
void f(double* h[],int n);
但是在这一个中,你传递一个指向数组的指针,该数组解析为指向指针,因为它是一个函数参数*。
*感谢Ben Voigt
答案 4 :(得分:1)
即使您通过指针传递了值,它指向的内存仍然可以通过函数进行更改。
答案 5 :(得分:0)
许多程序员都有一个关于编译器如何工作的心理模型,其中包括“数组只是一个指针”。这个模型不正确。
typedef int[10] Array;
typedef Array * PointerToArray;
typedef int * Pointer;
Array a = {0,1,2,3,4,5,6,7,8,9};
PointerToArray pa;
Pointer pint = a; // the compiler casts this automatically to a different type.
此时pint和pa具有相同的二进制值,但pa [1]和a [1]不引用内存中的相同位置。了解原因非常重要。