为什么一个函数可以接收一个char数组作为一个char指针,为什么这个函数可以改变一个元素的值?

eni9jsuy  于 2023-04-05  发布在  其他
关注(0)|答案(1)|浏览(104)

我声明了一个函数的参数,并把一个字符数组作为参数。
我被告知char指针和char数组是不同的类型。
但是函数可以有一个字符数组作为字符指针。
此外,可以改变char指针的一个元素,尽管参数是char指针。
下面是显示案例的代码。

#include<stdio.h>
void changeelement(char *p) {
  p[0]='v';
}
int main() {
    char array[]="boice";
    changeelement(array);
  printf("%s", array);
    return 0;
}

这就是结果。enter image description here
关于char指针和char数组的区别有很多答案,但没有这种情况的答案。
感谢您抽出宝贵的时间。

vuktfyat

vuktfyat1#

编译器将具有数组类型的参数调整为指向数组元素类型的指针。
所以这些函数声明

void changeelement(char p[100] );
void changeelement(char p[10] );
void changeelement(char p[] );

void changeelement(char *p );

都是等价的,并且声明了同一个函数。
来自C标准(6.7.6.3函数声明符(包括原型))
7将参数声明为“类型数组”应调整为“类型限定指针”,其中类型限定符(如果有的话)是在数组类型派生的[ and ]内指定的那些,如果关键字static也出现在数组类型派生的[ and ]内,那么对于函数的每次调用对应的实际参数的值将提供对数组的第一个元素的访问,该数组具有至少与size表达式所指定的元素一样多的元素。
你可以写例如在同一个程序

void changeelement( char *p ); 

void changeelement( char p[] ) 
{
    p[0] = 'v';
}

另一方面,用作参数表达式的数组被隐式转换为指向其第一个元素的指针。
来自C标准(6.3.2.1 L值、数组和函数指示符)
3除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则**类型为“array of type”的表达式将转换为类型为“pointer to type”的表达式,该类型指向数组对象的初始元素,并且不是左值。如果数组对象具有寄存器存储类,则行为未定义。
在C中,通过引用传递对象意味着通过指向对象的指针间接传递对象。从C标准:
“指针类型描述了一个对象,其值提供了对被引用类型的实体的引用。"**因此,解除对指针的引用,函数可以直接访问指针所指向的对象,并可以更改它。
举个例子

#include <stdio.h>

void f( int *p )
{
    *p = 10;
}

int main( void )
{
    int x = 0;

    f( &x );

    printf( "x = %d\n", x );
}

程序输出为

x = 10

类似地,当一个函数处理指向数组第一个元素的指针时,那么使用指针算术和解引用指针,函数可以改变数组的任何元素。
顺便说一下,上述函数可以重写为

void f( int p[] )
{
    p[0] = 10;
}

尽管参数表达式不使用数组。在任何情况下,即使你使用数组作为参数表达式,它也是隐式的;y转换为指向单个元素的指针:数组的第一个元素。

相关问题