我试图传递一个角色阵列' p'一个函数' func'并将其复制到另一个论点' arg'在功能里面。但是,阵列没有被复制,尽管我能够修改' p'在' func'并且能够验证主要功能的变化,' res'不会使用' p'中的值进行复制。它打印空白。我不确定自己犯了什么错误。
#include <stdio.h>
#include <stdlib.h>
void func(char *c, int size, char *res)
{
int i;
printf("Printing c in func...\n");
for(i=0;i<size;i++) {
printf("%c",c[i]);
}
printf("\n");
c[2] = 'j';
res = c;
}
int main(void)
{
char c[5]={'h','e','l','l','o'};
char *p,*arg;
int i, size = 5;
p=c;
arg = (char*)malloc(size);
func(p,size,arg);
printf("Printing p in main...\n");
for(i=0;i<size;i++) {
printf("%c",p[i]);
}
printf("\n");
printf("Printing arg in main...\n");
for(i=0;i<size;i++) {
printf("%c",arg[i]);
}
printf("\n");
return 0;
}
输出:
Printing c in func...
hello
Printing p in main...
hejlo
Printing arg in main...
答案 0 :(得分:2)
在C中,函数的参数按值传递。函数执行结束后,位置res
和c
不存在。请注意,您正在进行的更改是使用指针本身而不是位置指针指向的。因此res
无法看到对main
的任何更改。
要使更改对main
可见,您需要将arg
的地址传递给函数func
。
func
签名应为
void func(char *c, int size, char **res) ;
来自main
的来电应为
func(p, size, &arg);
同时将作业res = c;
中的作业*res = c;
更改为func
。
在这种情况下,您传递的是指针arg
的地址,并且对res
所指向的位置进行了更改。 res
指向reg
的地址,因此res
指向的地址所做的任何更改都将保留并main
可见。
现在看看它是如何工作的。最初在建议的更改后调用您的函数func
时:
+-----------+ (0x300 is a random memory location)
| |
arg | 0x300 | <---------+
| | |
+-----------+ |
0x100 |
|
|
+-----------+ |
| | |
res | 0x100 +-----------+
| |
+-----------+
0x200
当您将c
分配给*res
(别名为reg
)时,*res
会reg
指向c
分的位置至。假设字符hello
存储在0x500
,则*res = c
会reg
指向0x500
:
Array c (in main)
+-----------+ +-----+-----+-----+-----+-----+------+
| +--------------------------------->+ 'h' | 'e' | 'j' | 'l' | 'o' | '\0' |
arg | 0x500 | <---------+ +-----+-----+-----+-----+-----+-------
| | | 0x500 ....
+-----------+ |
0x100 |
| *res = c
|
+-----------+ |
| | |
res | 0x100 +-----------+
| |
+-----------+
0x200
答案 1 :(得分:1)
在C指针中,按值对函数进行篡改,所以在你的函数中:
void func(char *c, int size, char *res)
res是与传递给它的指针完全不同的对象
func(p, size, arg);
它与arg
不同,但它指向(仅指向)与传递给此函数时指向的arg
相同的位置。
因此分配
res = c;
疯狂的内部函数只更改本地指针(函数内部的一个)。如果你做了
*res = *c;
然后指向的内存将被更改,并且从函数外部可以看到,因为原始指针的内存指向 相同< / strong>作为res
指向的那个。这也是将'j'
写入c[2]
更改原始数组的原因:
c[2] = 'j'; /* note: this is same as *(c + 2) = 'j'; and this is why it works - you
are using memory pointed to by pointer */
如果您需要更改指针本身,则需要将地址传递给该指针:
void func(char *c, int size, char **res)