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

Why can a function receive a char array as a char pointer and why can the function change the value of an element?

提问人:hooky 提问时间:4/3/2023 最后编辑:Vlad from Moscowhooky 更新时间:4/3/2023 访问量:70

问:

我将 char 指针声明为函数的参数,并将 char 数组作为参数。

有人告诉我 char 指针和 char 数组是不同的类型。

但是该函数可以将 char 数组作为 char 指针。

此外,可以更改 char 指针的元素,尽管参数是 char pointer。

下面是展示案例的代码。

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

这就是结果。在此处输入图像描述

关于 char 指针和 char 数组的区别有很多答案,但这种情况没有答案。

感谢您抽出宝贵时间。

数组 C 指针 按引用传递隐 式转换

评论

1赞 user253751 4/3/2023
为什么你认为它不应该起作用?
0赞 Some programmer dude 4/3/2023
您的函数不会更改变量本身,而是会更改指向位置的内存。这是函数内数组的第一个元素。pparraymain
1赞 Some programmer dude 4/3/2023
关于数组和指针之间的关系,数组可以衰减为指向其第一个元素的指针。所以调用实际上和 .changeelement(array)changeelement(&array[0])
0赞 BoP 4/3/2023
这回答了你的问题吗?什么是数组到指针衰减?

答:

2赞 Vlad from Moscow 4/3/2023 #1

编译器将具有数组类型的参数调整为指向数组元素类型的指针。

所以这些函数声明

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

void changeelement(char *p );

等效并声明相同的一个函数。

来自 C 标准(6.7.6.3 函数声明符(包括原型))

7 将参数声明为 ''array of type'' 应为 调整为“限定的指向类型的指针”,其中类型限定符 (如果有)是在数组类型的 [ 和 ] 中指定的那些 派生。如果关键字 static 也出现在 [ 和 ] 中 数组类型派生,然后对于每次调用函数, 相应实际参数的值应提供对 数组的第一个元素,其元素数至少与指定的元素数相同 按大小表达式。

例如,您可以在同一个程序中编写

void changeelement( char *p ); 

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

另一方面,用作参数表达式的数组被隐式转换为指向其第一个元素的指针。

来自 C 标准(6.3.2.1 左值、数组和函数指示符)

3 除非它是运算符大小的操作数或一元数 & 运算符,或者是用于初始化数组的字符串文字,一个 类型为 ''array of 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 转换为指向单个元素的指针:数组的第一个元素。