指针和数组名的共同特点是都是用来指代一个地址的。
不同的是:
1、指针是需要占用内存空间来存储地址的;数组名则更像是一个立即数或者常数。你可以修改指针指向的内容,但你绝对无法改变数组名的指向。
2、数组和指针对于sizeof来说是不同的,指针变量占用的空间通常等于当前CPU的最大位数,数组名取sizeof的话,得到的则是数组的大小。、
但是把数组名作为参数传给一个形参为指针的函数,它在这个函数里就变成了普通指针,你用sizeof(数组名)得到的是指针大小而不是数组大小。
如果你的函数应该接收数组名而不是指针的话,那应该声明成:
void func(int arr[], int N); //其中N为数组大小。这样写之后在函数体里sizeof(arr)一样只会得到指针的大小而不会得到数组大小
而不是
void func(int *arr);
3、如果用extern声明一个外部变量,指针和数组不能混用。比如在文件1.cpp里声明了char ca[]=“abcde”,在文件2.cpp里如果要引用,那么必须是extern char ca[]而不是extern char * ca,因为前者是常数,后者是一个占用了内存空间的有效的变量,区别还是很大的。
4、对数组名取地址&是合法的,但有些编译器不推荐这样做,对数组名取地址的结果与直接使用数组名的结果是一致的,这是C语言的一种特殊规定。
有一个类似的效果就是函数名,假如func1是一个函数名,那么*func1==&func1==func1,这只是特殊用法,不代表函数名/数组名真的可以这么做。
作者:时国怀
链接:https://www.zhihu.com/question/23059655/answer/23485680
数组就是数组,但是他可以隐式转换成指针。当一个重载函数分别接受数组和指针的时候,肯定还是数组的那个命中。参见sizeof和strcpy_s。
数组不能被直接复制,所以当数组名作为函数参数的时候,要么就是数组的引用,要么就是指向第一个元素的指针,他们的值是相等的。当你对一个数组做&的时候,他提取的是指向数组的指针,然后仍然可以隐式转换成指向第一个元素的指针,而且它们的值是相等的。所以对于printf这种只认binary的函数来讲,自然会输出一样的结果。
作者:vczh
链接:https://www.zhihu.com/question/23059655/answer/23484315