如何从C中的函数返回数组?
大多数网站都这样说: C编程不允许将整个数组作为参数返回 对一个函数进行修改。但是,您可以通过以下方式返回指向数组的指针: 指定不带索引的数组名称 我刚开始讲指针,据我所知,指针变量是一个存储内存地址的变量。当我们使用*解除对它的引用时,我们到达那个内存地址并保存存储在那里的值。此外,对于数组,指针必须指向第一个元素 现在,如果我们的函数返回指向数组第一个元素的指针,如本例所示:如何从C中的函数返回数组?,c,arrays,pointers,C,Arrays,Pointers,大多数网站都这样说: C编程不允许将整个数组作为参数返回 对一个函数进行修改。但是,您可以通过以下方式返回指向数组的指针: 指定不带索引的数组名称 我刚开始讲指针,据我所知,指针变量是一个存储内存地址的变量。当我们使用*解除对它的引用时,我们到达那个内存地址并保存存储在那里的值。此外,对于数组,指针必须指向第一个元素 现在,如果我们的函数返回指向数组第一个元素的指针,如本例所示: int * myFunction() { . . . } 我们将如何去引用它 “函数返回指针”是
int * myFunction() {
.
.
.
}
*
,例如:
int z = 5;
int* pointer_to_z = &z; // get memory address of z and store that in pointer_to_z
int can_i_have_my_z_back_please = *z; // check what value is at that memory address and store it, a copy is made here.
“函数返回指针”是否意味着它正在返回
指针指向的内存地址
它返回一个指针变量,这个变量保存值的内存地址。基本上,“指向”值与“拥有它的地址”相同
什么是静态变量?我冲浪够多了,但没找到
任何令人满意的东西
关于静态变量已经是什么,有很多很好的答案。总而言之(仅限于变量的生存期,而非其链接),静态变量在初始化后对程序的其余部分有效,这意味着它的生存期不像局部变量那样受范围限制:
void hello()
{
int x = 5;
} // x destroyed here..
void hello_static()
{
static int x = 5;
} // x will only be destroyed at the "end" of the program
这反过来意味着返回本地静态变量的指针(内存地址)是完全安全的,因为静态变量仍然可以访问:
int* return_my_static()
{
static int a = 5;
return &a;
}
int main()
{
int* pointer_to_static = return_my_static(); // get the memory address of the static
printf("%i", *pointer_to_static); // print out the value by dereferencing
}
但是,对局部非静态变量执行此操作将导致未定义的行为,因为指向的变量(其内存地址)已被销毁,因此不再有效:
int* return_local()
{
int a = 5;
return &a;
} // a is destroyed here.. oopsies
int main()
{
int* pointer_to_local = return_local(); // get the memory address of the local.
//local variable has been destroyed now and 'pointer_to_static' now points to garbage memory!
printf("%i", *pointer_to_local); // Try to print out the value by dereferencing, this is undefined behaviour, anything can happen.
}
请注意,上面的代码可能会运行并输出预期结果,但这纯粹是运气,这是未定义的行为,应该不惜一切代价避免,因为此时可能发生任何事情。问题3:
int a;
void foo() {
int b
static int c;
}
int main() {
foo();
}
当程序启动时,a和c的内存被分配并保持分配状态,直到程序退出。所以在任何给定的时间,a和c上都有。每次有人(此处为main)调用foo时,都会在堆栈上分配b,直到该函数返回为止
关于问题3前面的引述:
int a;
void foo() {
int b
static int c;
}
int main() {
foo();
}
返回a和c的地址没有问题,因为只要程序运行,它们就存在,但将地址返回到b是一个错误,因为调用方一拿到指针,指针就指向无效内存
问题1:
在指针前面放一个星号可以解除对它的引用。没关系,指针指向的是什么。如果它是一个数组,您可以增加或减少指针以获得您试图达到的索引,就像在一个简单的加法中:*(p+4)将访问第五个元素(因为*(p+0)是第一个元素,所以*(p+1)是第二个元素,依此类推)
除了写*(p+4),你还可以写p[4]
假设函数如下所示:
int * myFunction() {
static int array[8];
return array;
}
然后return语句将返回数组的地址,该地址与数组的第一个元素的地址完全相同
因此,具有int*p=myFunction();然后,您可以使用直观的语法p[0]=42;访问数组。。。;p[7]=23
问题2:
返回指针的函数就是返回指针的函数。指针是指向内存中某个点的东西。通常这称为内存地址,但C语言并不关心。因此,在实践中,“函数返回指针”意味着它返回指针指向的内存地址,是的。返回到前面:
什么是静态变量
当程序首次启动时,具有静态
存储持续时间的对象已为其分配了存储空间,并且该存储空间一直保持到程序退出。在以下情况下,对象具有静态
存储持续时间:
- 其标识符在文件范围内声明(在任何函数体之外);或
- 它的标识符是用
关键字声明的static
#include <stdio.h>
int g_var; // static storage duration
void foo( void )
{
static int s_var = 10; // static storage duration
int l_var = 10; // auto storage duration
printf( "g_var = %d, s_var = %d, l_var = %d\n", g_var++, s_var++, l_var );
}
l_var
具有auto
存储持续时间-其生存期仅限于foo
函数的生存期。每次调用foo
时,在函数进入时分配和初始化l_var
的新实例的存储,并在函数退出时释放。这很重要-l_var
在退出foo
时停止存在,因此当foo
返回1时,指向它的任何指针都将无效
这就是为什么你不能做这样的事情
int * bar( void )
{
int array[N];
...
return array;
}
因为数组
int * bar( void ) { static int array[N]; ... return array; }
void foo( int *array, size_t arraySize )
{
...
array[i] = some_value;
...
}
int * bar( void )
{
int *array = malloc( sizeof *array * N );
if ( array )
{
// initialize array contents
}
return array;
}
int *p = bar();
printf( "p[0] = %d\n", *p );
printf( "p[0] = %d\n", *(p + 0) );
printf( "p[0] = %d\n", p[0] );