(转)数组名、数组名取地址以及作为函数传递带来的问题

//数组地址以及作为函数传递带来的问题
#include "stdafx.h"
#include <iostream>
using namespace std;
void test(int a[5]);
void test2(int a[5]);
int _tmain(int argc, _TCHAR* argv[])
{
 int a[5]={1,2,3,4,5};
 cout<<"sizeof a is: "<<sizeof(a)<<endl;
 test(a);
 cout<<endl<<"*****(in function) begin test2(a) *****"<<endl<<endl;
 test2(a);
 cout<<endl<<"***** end test2(a)   *****"<<endl<<endl;
 cout<<endl<<"***** begin repeat content of test2 in main function without passing array parameter ********"<<endl<<endl; 
 printf("(a) is: %d, (&a) is: %d\n",(a),(&a));
 printf("(a+1) is: %d, (&a+1) is: %d\n",(a+1),(&a+1));
 printf("*(a+1) is: %d, *(&a+1) is: %d\n",*(a+1),*(&a+1));
 cout<<endl<<"***** end repeat content of test2 in main function without passing array parameter ********"<<endl<<endl; 
 while(1){};
 return 0;
}
void test(int a[5])
{
 printf("size of(a) as function parameter is %d\n",sizeof(a)); //结果?
}
void test2(int a[5])       //形参是int(*)[5]型
{
 printf("(a) is: %d, (&a) is: %d\n",(a),(&a));    //其实这里a是形参int(*a)[5],而&a是形参的地址,与作为实参a的&a不是一回事
 printf("(a+1) is: %d, (&a+1) is: %d\n",(a+1),(&a+1));
 printf("*(a+1) is: %d, *(&a+1) is: %d\n",*(a+1),*(&a+1));
}

//总结(参考了《再再论指针》by飞天御剑流):

//1:数组名a实际上是一个符号常量,是一个右值,是数组首地址(为具有数组类型的地址),其值等于&a[0](与a不同,&a[0]为int*型的地址)。a+i跨过i个sizeof(int),运算结果为&a[i]

 

//2: a[1]中[]符号实际上相当于替换成*(a+1)

 

//3.对于&*a的组合,编译器会优化成a。因为&*相互抵销

 

//4. 由于数组名为右值而非变量(左值),对数组名取地址&a属于实现上不确定的操作。C语言标准为了使&操作符能够用于任何可进行寻址操作的实体而允许该操作,并将其定为取得数组对象的首地址,且有&a==a. 但是,&a的意义,已经不是对一个数组名取地址,而是对一个数组对象取地址

 

//5:&a的类型是int (*)[5],即代表整个“数组对象”,&a+1跨过一个sizeof(a),等价于a[5]

 

//6:数组作为参数传递给函数时会退化成指针(即将数组首地址赋值给作为形参的int(*)[5]型指针) 其size=4,而不是数组的长度了

 

//7: 数组名a作为参数传递给函数后,函数中的a实际上指的是形参int* a,&a实际上是对形参int* a取地址,所以此时&a!=a

 

未命名

 

-----------------------------对于二维数组--------------------------------------------------------------------------------------------------------

 

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    double a[2][3]={{1,2,3},{4,5,6}};
    wcout<<"double a[2][3]={{1,2,3},{4,5,6}}"<<endl;
    wcout<<"***********以下几个值相等***********"<<endl;
    wcout << "(a):"<<a << endl;
    wcout << "(&a):"<<&a << endl;
    wcout << "(&a[0][0]):"<<&a[0][0] << endl;
    wcout << "(a[0]):"<<a[0] << endl;
    wcout << "(&a[0]):"<<&a[0] << endl;
    wcout<<"************************************"<<endl;
    wcout<<endl;
    wcout<<endl;
    wcout<<"double a[2][3]={{1,2,3},{4,5,6}}"<<endl;
    wcout<<"***********加1之后,长度分别增加了多少***********"<<endl;
    wcout << "(a+1):"<<(a+1)<<"---加1,跨越了3个double类型的长度" << endl;
    wcout << "(&a[0]+1):"<<(&a[0]+1) << "---加1,跨越了3个double类型的长度" << endl;
    wcout << "(&a+1):"<<(&a+1) <<"---加1,跨越了6个double类型的长度" << endl;
    wcout << "(&a[0][0]+1):"<<(&a[0][0]+1) <<"---加1,跨越了1个double类型的长度" << endl;
    wcout << "(a[0]+1):"<<(a[0]+1) << "---加1,跨越了1个double类型的长度" << endl;
    wcout<<"***********************************************"<<endl;
    wcout<<endl;
    wcout<<endl;
    wcout<<"double a[2][3]={{1,2,3},{4,5,6}}"<<endl;
    wcout<<"***********求长度的结果***********"<<endl;
    wcout << "sizeof(a):"<<sizeof(a)<<"-------二维数度的长度"<< endl;
    wcout << "sizeof(&a):"<<sizeof(&a)<<"------指针的长度" << endl;
    wcout << "sizeof(a[0][0]):"<<sizeof(a[0][0])<<"------数据类型double的长度"<< endl;
    wcout << "sizeof(&a[0][0]):"<<sizeof(&a[0][0])<<"------指针的长度"<< endl;
    wcout << "sizeof(a[0]):"<<sizeof(a[0])<<"------a[0]所指向的一维数度的长度"<<endl;
    wcout << "sizeof(&a[0]):"<<sizeof(&a[0])<<"------指针的长度"<< endl;
    wcout<<"***************************************"<<endl;
 while(1){};
 return 0;
}
未命名山东省
posted @ 2012-05-07 21:28  ForFreeDom  阅读(3064)  评论(0编辑  收藏  举报