今天一个朋友问了我他的程序怎么输出的结果不对,对于一个简单的求数组长度的小问题竟然发现还有那么多门道,程序如下:
void merge(int *A, int p, int q, int r)
{
int n1 = q-p+1;
int n2 = r-q;
int* L = new int(n1+1);
int* R = new int(n2+1);
for(int i=0; i<n1; i++)
{
L[i] = A[p+i-1];
}
for(int j=0; j<n2; j++)
{
R[j] = A[q+j];
}
L[n1]=100000.0;
R[n2]=100000.0;
int a=0;
int b=0;
for(int k=p-1; k<r; k++)
{
if(L[a]<=R[b])
{
A[k] = L[a];
a=a+1;
}
else
{
A[k] = R[b];
b=b+1;
}
}
for(int i=0; i<sizeof(A)/sizeof(int);i++)
{
cout<<A[i]<<endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int A[] = {2,4,6,8,1,3,7,9};
merge(A,2,4,7);
return 1;
}
在开始看到这短代码时其实就感觉在
merge中for(int i=0; i<sizeof(A)/sizeof(int);i++)计算数组的长度这样不对,通过调试也确实发现这里计算出的数组的长度一直为1,通过查找资料才发现如果数组以参数的传递到子函数中,在子函数中这样计算数组的长度是不可行的。因为,A是函数参数,到了子函数中,a只是一个指针(地址,系统在子函数运行时,是不知道A所表示的地址有多大的数据存储空间,这里只是告诉函数:一个数据存储空间首地址),所以,sizoef(A)的结果是指针变量a占内存的大小。但是在定义数组的函数内这样求数组的长度依然是很有效的。
到这里还没完,我在调试的时候意外的发现sizeof(A)的长度是4,按照以往的理解,我的系统是64位的,那么地址大小应该是8个字节才对啊,然后发现这也和使用的VS中配置的目标平台有关,因为默认使用的是win32,所以计算出来的地址统统都是4个字节,我改成x64之后,发现确实变成了8字节了。
看来想彻底懂一门编程语言还有很长的路要走啊,其中语言点的博大精深还需要继续学习。