在下面的程序中,调用change_it()似乎没有效果。请解释并更正代码?

在下面的程序中,调用change_it()似乎没有效果。请解释并更正代码?,c,C,本部分如下: void change_it(int[]); int main() { int a[5],*p=1; void change_it(int[]); printf("p has the value %u \n",(int)p); change_it(a); p=a; printf("p has the value %u \n",(int)p); return 0; } void change_it(int[])

本部分如下:

void change_it(int[]);

int main()
{
    int a[5],*p=1;

    void change_it(int[]);

    printf("p has the value %u \n",(int)p);

    change_it(a);

    p=a;

    printf("p has the value %u \n",(int)p);

    return 0;
}

void change_it(int[]) {

    int i=777, *q=&i;

    a = q; // a is assigned a different value
}
该语句不仅有效,据我所知,不能在C中的另一个函数中声明函数

此外:

此函数需要参数,但您只提供了int[]类型, 无效更改\u it a[]解决了此问题

此部分:

void change_it(int[]);

int main()
{
    int a[5],*p=1;

    void change_it(int[]);

    printf("p has the value %u \n",(int)p);

    change_it(a);

    p=a;

    printf("p has the value %u \n",(int)p);

    return 0;
}

void change_it(int[]) {

    int i=777, *q=&i;

    a = q; // a is assigned a different value
}
该语句不仅有效,据我所知,不能在C中的另一个函数中声明函数

此外:

此函数需要参数,但您只提供了int[]类型,
void change\u itint a[]修复了问题

您的程序不会编译并生成警告。它不会像你想的那样工作

1p是指针。要访问它所指向的值,必须使用*解引用运算符对其进行解引用

二,

在主体中不需要

三,

对变革的调用似乎没有任何效果

如果要更改函数中的[0]元素,请将传递参数命名为a并取消引用q指针

工作程序可能如下所示:

void change_it(int[]); 

您的程序不会编译并产生警告。它不会像你想的那样工作

1p是指针。要访问它所指向的值,必须使用*解引用运算符对其进行解引用

二,

在主体中不需要

三,

对变革的调用似乎没有任何效果

如果要更改函数中的[0]元素,请将传递参数命名为a并取消引用q指针

工作程序可能如下所示:

void change_it(int[]); 

好的,我相信您对函数没有基本的理解:首先让我们从声明和定义开始:

函数的声明只需要将参数名作为参数类型的可读性,其中as定义必须有参数名,因为定义中的参数是局部变量

void change_it(int[]); // THIS IS DECLARATION
int main ()
{
   void change_it(int[]); // THIS IS DECLARATION (duplicate and unnecessary 
   ....
}

void change_it(int[] a) // THIS IS DEFINITION 
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
这将打印p的地址,而不是p的值。所以这应该是

printf("p has the value %u \n",(int)p);
最后我们得到一个函数体。您依赖于已在本地分配并将其放回参数中的某个对象

printf("p has the value %u \n", *p);

所以q是指针,你们给它分配了局部变量i的地址。那么当你的程序存在这个函数时会发生什么呢?我可能会消失,因此失去了它的值和地址,分配给q意味着q失去了它的变量和值,分配给a可能失去它的变量,因为它在函数中指向i。

好的,我相信您对函数没有基本的理解:首先让我们从声明和定义开始:

函数的声明只需要将参数名作为参数类型的可读性,其中as定义必须有参数名,因为定义中的参数是局部变量

void change_it(int[]); // THIS IS DECLARATION
int main ()
{
   void change_it(int[]); // THIS IS DECLARATION (duplicate and unnecessary 
   ....
}

void change_it(int[] a) // THIS IS DEFINITION 
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
这将打印p的地址,而不是p的值。所以这应该是

printf("p has the value %u \n",(int)p);
最后我们得到一个函数体。您依赖于已在本地分配并将其放回参数中的某个对象

printf("p has the value %u \n", *p);

所以q是指针,你们给它分配了局部变量i的地址。那么当你的程序存在这个函数时会发生什么呢?我可能会消失,因此失去了它的值和地址,分配给q意味着q失去了它的变量和值,分配给a意味着q失去了它的变量,因为它在函数中指向i。

首先,初始化p时,给指针的值是1,当它需要一个内存位置时。NULL使用0,但这并不意味着您可以或应该只为指针分配整数值

仅供参考,您可以按如下方式计算1的值:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
但是,这样做有-2个原因,第-1个原因是应该尊重C提供的最小类型安全性,第-2个原因是它使代码难以为其他人理解

我将假设您要做的不是声明一个地址值为1的指针,而是声明一个包含值为1的指针。除非已经有另一个变量保存值1,否则必须首先动态分配指针,然后设置其值

int a[5], *p = (int *) 1;
如果要使用另一个变量,可以在堆栈上创建指针,而不是动态分配它,如下所示:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
现在,对这两个函数调用相同的print函数将产生以下结果:

int* q;
q = p;
输出: p的值为1 q的值为1

要解决您的主要问题,您需要在change_it函数中命名参数,例如:

printf("p has the value %d\n", *p);
printf("q has the value %d\n", *q);
您的程序需要命名参数,否则它不知道您正在尝试引用数组。在函数中引用的变量a不绑定到任何东西;编译程序 会知道你在说什么

此外,您不需要在主函数中重新声明函数原型。这不是编译器错误的原因是您可以有任意多个声明,但只能有一个定义。不过,也没有理由这么做

另外,您不必在函数原型中命名参数,但最好同时命名它们,并与原型和实际实现之间的名称保持一致,以便阅读您的代码的人了解发生了什么

另外,您正在为printf函数使用%u说明符,而实际上没有使用无符号十进制数。您使用的是有符号小数,因此应该使用%d

最后,change_it函数犯了一个严重错误,使它无法正确更改传入数组的值:将传入的数组设置为q值

仔细查看原始代码中的函数,假设您将输入数组命名为a,就像您的意思一样。首先声明一个整数变量i,并将其值设置为777。然后,在堆栈上创建一个整数指针变量q,并将其值正确设置为i。注意:您没有将q设置为i的值,而是i的地址

为什么这个小而重要的区别很重要?当您在下一行中将a设置为q时,您正在更改数组的地址,特别是五元素整数数组的第一个元素,以指向整数变量的地址。这不好有几个原因。首先,数组的长度是五个整数,但现在它指向一个元素。如果并且当您尝试访问元素2-5时,您将因为尝试访问您不拥有的内存而得到无意义的垃圾或分段错误。更糟糕的是,变量i是在堆栈上分配的,因此当函数更改它的存在时,函数的数据将从堆栈中弹出,尝试访问i的地址将产生垃圾或分段错误,因为尝试访问您不拥有的内存。看到模式了吗

我不确定如何更正此代码,因为我不确定您试图完成什么,但更正上述错误后,您的代码现在看起来如下所示:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
注意:您的内存地址可以而且可能会与这些不同,重要的是p和a在这两者中是相等的


无论如何,希望这有帮助。如果您有任何问题,请告诉我。

首先,当您初始化p时,当指针需要一个内存位置时,您给它的值是1。NULL使用0,但这并不意味着您可以或应该只为指针分配整数值

仅供参考,您可以按如下方式计算1的值:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
但是,这样做有-2个原因,第-1个原因是应该尊重C提供的最小类型安全性,第-2个原因是它使代码难以为其他人理解

我将假设您要做的不是声明一个地址值为1的指针,而是声明一个包含值为1的指针。除非已经有另一个变量保存值1,否则必须首先动态分配指针,然后设置其值

int a[5], *p = (int *) 1;
如果要使用另一个变量,可以在堆栈上创建指针,而不是动态分配它,如下所示:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
现在,对这两个函数调用相同的print函数将产生以下结果:

int* q;
q = p;
输出: p的值为1 q的值为1

要解决您的主要问题,您需要在change_it函数中命名参数,例如:

printf("p has the value %d\n", *p);
printf("q has the value %d\n", *q);
您的程序需要命名参数,否则它不知道您正在尝试引用数组。在函数中引用的变量a不绑定到任何东西;编译器将知道你能推断出你在说什么

此外,您不需要在主函数中重新声明函数原型。这不是编译器错误的原因是您可以有任意多个声明,但只能有一个定义。不过,也没有理由这么做

另外,您不必在函数原型中命名参数,但最好同时命名它们,并与原型和实际实现之间的名称保持一致,以便阅读您的代码的人了解发生了什么

另外,您正在为printf函数使用%u说明符,而实际上没有使用无符号十进制数。您使用的是有符号小数,因此应该使用%d

最后,change_it函数犯了一个严重错误,使它无法正确更改传入数组的值:将传入的数组设置为q值

仔细查看原始代码中的函数,假设您将输入数组命名为a,因为 看来你是有意的。首先声明一个整数变量i,并将其值设置为777。然后,在堆栈上创建一个整数指针变量q,并将其值正确设置为i。注意:您没有将q设置为i的值,而是i的地址

为什么这个小而重要的区别很重要?当您在下一行中将a设置为q时,您正在更改数组的地址,特别是五元素整数数组的第一个元素,以指向整数变量的地址。这不好有几个原因。首先,数组的长度是五个整数,但现在它指向一个元素。如果并且当您尝试访问元素2-5时,您将因为尝试访问您不拥有的内存而得到无意义的垃圾或分段错误。更糟糕的是,变量i是在堆栈上分配的,因此当函数更改它的存在时,函数的数据将从堆栈中弹出,尝试访问i的地址将产生垃圾或分段错误,因为尝试访问您不拥有的内存。看到模式了吗

我不确定如何更正此代码,因为我不确定您试图完成什么,但更正上述错误后,您的代码现在看起来如下所示:

void change_it(int[] a)
{
   int  i=777, *q=&i;

   a = q; // a is assigned a different value
}
int* p = malloc(sizeof(int));
*p = 1;
void change_it(int arr[])
注意:您的内存地址可以而且可能会与这些不同,重要的是p和a在这两者中是相等的



无论如何,希望这有帮助。如果您有任何问题,请告诉我。

此代码不编译,它显示参数省略错误您到底想调用什么void change\u itint[];具有您已经在文件顶部声明了它;只需使用change_it/*some int array*/.u来调用它。u是为了打印未签名的内容,传递一个int whhch是有符号的调用未定义的行为。此代码不编译,它显示了参数省略错误。您究竟想调用void change_it[]什么;具有您已经在文件顶部声明了它;只需使用change_it/*一些int数组*/来调用它。u是printf unsigned的东西,传递整数whhch是有符号的调用未定义的行为。这给运行时错误UB是因为指向堆栈变量的指针这给运行时错误UB是因为指向堆栈变量的指针这给运行时错误UB是因为指向堆栈变量的指针这给运行时错误UB是什么给运行时错误?&我是问题的核心哦,是的,很好!!!!我的注意力集中在其他方面:我在想我的printf语句。这是由于指向堆栈变量的指针导致的运行时错误UB是什么导致了运行时错误?&我是问题的核心哦,是的,很好!!!!我专注于其他事情:我在想我的printf statement.code修正了上面的UB,但很难想象Asker的主要思想是什么。这是不是有计划的。问题出在question@JacekCz你好,Jacek,谢谢你的评论。你是对的。我们只知道改变必须有效果。既然a被传递给change_,我们可以假设a元素的修改是计划好的。代码对上面的UB进行了更正,但很难想象Asker的主要思想是什么。这是不是有计划的。问题出在question@JacekCz你好,Jacek,谢谢你的评论。你是对的。我们只知道改变必须有效果。由于a被传递给change_it,我们可以假设a元素的修改是计划好的。