剖析数组名、函数名(不是指针常量,更不是指针)

        对于一个数组,如 int a[4];  如果只是给出数组名a,编译器不知道该取该数组的第几个元素,因此编译器不会自动取值,而是返回该数组的首地址(第一个元素的地址)。其实,数组名a就是数组本身,并不是数组的首地址,只是当只是给出了数组名a的时候,而又同时需要取值时,数组名a才会被隐式转换为该数组的首地址。因此,int *p=&a;和int *p=a的效果是一样的,只是前者是显示的,而后者是隐式的。

        例如,数组名a在以下情况就不是数组的首地址的:1.sizeof(a)  得到的结果为16,即a是一个数据类型,长度为4的int数组类型,是数组本身,没有进行隐式转换;2.&a   表示数组的首地址,并不是指针的指针,而是指向长度为4的int数组的指针,一个常量指针,其指针类型为: in (*)[4],此处4不能省略,因为"指向不确定长度的指针" 是没有意义的,编译器若不知道该指针指向的类型,就无法编译指针的加减法运算(指针指向类型的长度未知,加减法的位移量就未知)。int (*p)[4]=&a; 定义一个指针p,并初始化为数组a的地址,等价于:int *p=a;  3. C++中取引用时a也不是指针。

char* test2()
{
    char p[] = "hello world";
    return p;
}  //错误代码

char* test2()
{
    char *p = "hello world";
    return p;
}

        对于以上代码,char p[ ] = "hello world";与char *p = "hello world";是有着本质区别的,前者首先定义了一个数组p,且用后面的字符串初始化该数组p,数组p的作用域为该函数内部,数组生存期和作用域与声明方式相关。而且该数组没有 const 资格符,字符串内容是可以修改的。这个数组首地址不能在函数中返回(因为函数结束的同时,p已经被销毁了),除非声明用了 static 。对于后者,声明一个指针。字符串字面量本身成为一个静态存储期的数组,它再隐式转换成指针以初始化声明的指针。这个字符串是不可修改的(修改会导致未定义行为,数组本身可放在只读内存区)。它的首地址可以在函数中返回。

        对于函数名,其原理与上面基本相同。函数名其实并不是函数的入口地址,只是被隐式转换了。函数名只是函数本身。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值