我对 C 还很陌生,刚刚开始学习。如果这个问题看起来有点愚蠢,我深表歉意。
有人可以解释一下为什么这不起作用吗?有什么办法可以完成这样的事情吗?非常感谢!
struct test{
int arr[10];
};
void foo(struct test t){
t.arr[0] = 1;
}
int main() {
struct test t = {malloc(10*sizeof(int))};
foo(t);
printf("%d", t.arr[0]);
}
Run Code Online (Sandbox Code Playgroud)
我不确定为什么 t.arr[0] 没有分配给 1。
C 是一种完全按值传递的语言。foo接收其参数的按字节副本,即使对于结构也是如此。t修改内部的局部变量foo不会修改t内部的变量main变量。
每当内存为一个时,该结构成员int arr[10];就会自动分配为十个数组intstruct test。您不需要单独分配它。
struct test t = {malloc(10*sizeof(int))};\nRun Code Online (Sandbox Code Playgroud)\n显然是错误的,导致报告以下诊断gcc:
struct test t = {malloc(10*sizeof(int))};\nRun Code Online (Sandbox Code Playgroud)\n如果您没有看到这样的诊断信息,则应该打开编译器警告。
\ngcc或clang使用-Wall和-Wextra,msvc使用/W4或/Wall.如果你这样做看到类似的诊断信息,请不要忽略它们
\ngcc或clang使用-Werror,msvc/WX以确保你不能。
\n传递指针值允许您取消引用该指针,并对它指向的对象进行修改:
\n#include <stdio.h>\n#include <stdlib.h>\n\nstruct test{\n int arr[10];\n};\n\nvoid foo(struct test *t){\n t->arr[0] = 1;\n}\n\nint main() {\n struct test t = { 0 };\n foo(&t);\n printf("%d\\n", t.arr[0]);\n}\nRun Code Online (Sandbox Code Playgroud)\nfoo.c: In function \xe2\x80\x98main\xe2\x80\x99:\nfoo.c:13:22: warning: initialization of \xe2\x80\x98int\xe2\x80\x99 from \xe2\x80\x98void *\xe2\x80\x99 makes integer from pointer without a cast [-Wint-conversion]\n 13 | struct test t = {malloc(10*sizeof(int))};\n | ^~~~~~\nfoo.c:13:22: note: (near initialization for \xe2\x80\x98t.arr[0]\xe2\x80\x99)\nfoo.c:13:21: warning: missing braces around initializer [-Wmissing-braces]\n 13 | struct test t = {malloc(10*sizeof(int))};\n | ^\n |\nRun Code Online (Sandbox Code Playgroud)\n需要注意的是,如果结构包含指针,那么该指针当然会按值复制到本地结构。这意味着它指向的任何内容都由两个结构共享(只要它们的生命周期重叠)。
\n可以执行以下操作
\n#include <stdio.h>\n#include <stdlib.h>\n\nstruct test{\n int *arr;\n};\n\nvoid foo(struct test t){\n t.arr[0] = 1;\n}\n\nint main() {\n int array[10];\n struct test t = { .arr = array };\n foo(t);\n printf("%d", t.arr[0]);\n}\nRun Code Online (Sandbox Code Playgroud)\n但这通常不是一个很好的设计模式。
\n