何时是数组名或函数名';转换为';变成指针?(C)中
1)误解:何时是数组名或函数名';转换为';变成指针?(C)中,c,arrays,function,pointers,function-pointers,C,Arrays,Function,Pointers,Function Pointers,1)误解: 无论何时用C语言声明数组,都会隐式创建指向数组第一个元素(数组名称)的指针(是吗?我不这么认为!) 页面的前两行(尽管我不确定信息的正确性)说明了相同的情况 正如我们所看到的,当我们声明一个数组时,一个连续的内存块被分配给数组的单元,一个指针单元(适当类型)也被分配并初始化为指向数组的第一个单元。 但是当我输出包含在该指针中的地址和该指针的地址时,结果是相同的。 所以,我认为指针毕竟不是被创建的 2)我是从问题中学来的 在大多数情况下,数组名被转换为指针。 当编译器决定
- 无论何时用C语言声明数组,都会隐式创建指向数组第一个元素(数组名称)的指针(是吗?我不这么认为!)
- 页面的前两行(尽管我不确定信息的正确性)说明了相同的情况 正如我们所看到的,当我们声明一个数组时,一个连续的内存块被分配给数组的单元,一个指针单元(适当类型)也被分配并初始化为指向数组的第一个单元。
- 但是当我输出包含在该指针中的地址和该指针的地址时,结果是相同的。 所以,我认为指针毕竟不是被创建的
- 在大多数情况下,数组名被转换为指针。
intsquare(int,int)
,任何square
,&square
,*square
,**square
都指向同一个函数指针。你能解释一下吗
编辑:代码段
int fruits[10];
printf("Address IN constant pointer is %p\n", fruits);
printf("Address OF constant pointer is %p\n", &fruits);
输出:
Address IN constant pointer is 0xbff99ca8
Address OF constant pointer is 0xbff99ca8
简短的回答是肯定的……除了有时。通常在声明数组后,每次使用其名称时,都会将其转换为指向数组对象的第一个元素的指针。但是,在某些情况下,这种情况不会发生。在@KeithThompson的回答中可以找到这些没有发生这种情况的案例
与数组类似,函数类型也将转换为指针值…有时除外。在@KeithThompson的回答中可以再次找到这种情况不再发生的情况 数组类型的表达式将隐式转换为指向数组对象的第一个元素的指针,除非它是:
- 一元
和
运算符的操作数李>
的操作数;或sizeof
- 初始值设定项中的字符串文字,用于初始化数组对象
char arr[6] = "hello";
“hello”
是一个数组表达式,类型为char[6]
(5加1表示'\0'
终止符)。它没有转换成地址;“hello”的完整6字节值被复制到数组对象arr
另一方面,在这方面:
char *ptr = "hello";
数组表达式“hello”
“衰减”为指向'h'
的指针,该指针值用于初始化指针对象ptr
。(实际上应该是const char*ptr
,但这是一个次要问题。)
函数类型的表达式(如函数名)将隐式转换为指向函数的指针,除非:
- 一元
和
运算符的操作数;或
(sizeof
的操作数非法,不是指针大小)sizeof function\u name
int
-to-float
转换那样,获取操作数的值并用它来计算结果的值。相反,数组或函数类型的表达式是“转换”的在编译时转换为指针类型的表达式。在我看来,“调整”一词比“转换”更清楚
请注意,数组索引运算符[]
和函数调用“operator”()
都需要指针。在像func(42)
这样的普通函数调用中,函数名func
将“衰减”为指向函数的指针,然后在调用中使用该指针。(只要函数调用做正确的事情,这种转换实际上不需要在生成的代码中执行。)
函数规则有一些奇怪的后果。在大多数上下文中,表达式func
转换为指向函数func
的指针。在&func
中,func
不会转换为指针,但&
会生成函数的地址,即指针值。在*func
中,func
隐式转换为指针,然后*
取消对它的引用以生成函数本身,然后(在大多数上下文中)将其转换为指针。在**func
中,这种情况会重复发生
(C11标准草案指出数组还有另一个例外,即数组是新的\u Alignof
运算符的操作数。这是草案中的一个错误,在最终发布的C11标准中已更正;\u Alignof
只能应用于括号中的类型名,而不能应用于表达式。)
数组的地址及其第一个成员的地址:
int arr[10];
&arr; /* address of entire array */
&arr[0]; /* address of first element */
是相同的内存地址,但类型不同。前者是整个数组对象的地址,类型为int(*)[10]
(指向10int
s数组的指针);后者的类型为int*
。这两种类型不兼容(例如,您不能合法地将int*
值分配给int(*)[10]
对象),指针算法在这两种类型上的行为不同
有一条单独的规则规定,数组或函数类型的声明函数参数在编译时调整(未转换)为指针参数。例如:
void func(int arr[]);
这正是情商
void func(int *arr);
int fruits[10];
printf("Address IN constant pointer is %p\n",fruits);
printf("Address OF constant pointer is %p\n",&fruits);
int fruits[10];
printf("Address IN constant pointer is %p\n", (void*)fruits);
printf("Address OF constant pointer is %p\n", (void*)&fruits);