当您不知道程序开始时的长度时如何在多个函数中使用数组
How to use an array in multiple functions when you don't know what the length will be at the start of your program
我有一个项目,我需要在两个不同的函数中使用一个数组,但它的长度因命令行参数而异,所以我以后才知道它是什么。我如何全局初始化数组,但是当我知道长度后我可以更改长度。这是我能做的问题的最简化版本:
#define _XOPEN_SOURCE 500
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
char tile_numbers[1];
void print (void);
int main (void)
{
int x = 7;
char tile_numbers[x];
tile_numbers[0] = 'h';
tile_numbers[1] = 'e';
tile_numbers[2] = 'l';
tile_numbers[3] = 'l';
tile_numbers[4] = 'o';
tile_numbers[5] = '!';
print();
}
void print (void)
{
for(int i = 0; i < 10 ; i++)
{
printf("char: %c", tile_numbers[i]);
}
}
您可以使用 malloc()
动态分配内存,而不是数组。假设在 运行 时,您将数组的大小存储在 int
变量 n
中。然后,您可以使用
分配内存
char *tile_numbers = (char*)malloc(sizeof(char)*n);
然后,您可以像以前一样为内存位置编制索引,如 tile_numbers[i]
用于 0
到 n-1
范围内的任何 i
。
如果需要全局声明,将声明和赋值分开。在全球范围内,使用
char *tile_numbers;
在获取尺寸的函数中,
tile_numbers = (char*)malloc(sizeof(char)*n);
此外,如果需要调整内存大小,可以使用realloc()
,
tile_numbers = (char*)realloc(tile_numbers,new_size);
不要使用全局 - 在main
(或最初分配的任何地方)定义数组,然后将其作为参数传递给函数需要使用它:
void print( size_t size, const char *arr)
{
for ( size_t i = 0; i < size; i++ )
printf( "char: %c\n", arr[i] );
}
int main( int argc, char **argv )
{
// define tileNumbers here -- we'll get into details below
print( arraySize, tileNumbers );
return 0;
}
不要养成使用全局(文件范围)变量的习惯 - 它会导致代码难以维护和扩展。 有时这是有道理的,但你还不知道那些时间是什么时候。通常,函数应该只通过参数或 return 值共享信息;他们不应该共享全局状态。
因为直到运行时才知道 tileNumbers
需要多大,所以不能将其分配为固定大小的数组并在以后调整大小。在知道大小之前,您需要推迟数组的定义。
在 C99 之前,您唯一的选择是使用动态内存(即 malloc
或 calloc
):
#include <stdlib.h> // for malloc declaration
...
size_t arraySize = getArraySize( ); // where getArraySize is a stand in for any code that sets arraySize
char *tileNumbers = malloc( sizeof *tileNumbers * arraySize );
if ( tileNumbers )
{
// code to initialize tileNumbers goes here
print( arraySize, tileNumbers );
// deallocate memory when we're done with it
free( tileNumbers );
}
从 C99 开始,您可以使用所谓的 可变长度数组 (VLA)。 VLA 的行为主要 类似于常规的固定长度数组,但由于其大小直到运行时才知道,因此不能在文件范围内声明(不能将其用作global), 不能是 struct
或 union
类型的成员,并且在其声明中不能有初始化器。
size_t arraySize = getArraySize( ); // where getArraySize is a stand in for any code that sets arraySize;
char tileNumbers[arraySize];
// code to initialize tileNumbers goes here
print( arraySize, tileNumbers );
无论如何,print
的原型将保持不变。在第一种情况下,我们传递一个指针。在第二种情况下,我们传递一个数组表达式,在计算时 decays 到一个指针表达式。
我有一个项目,我需要在两个不同的函数中使用一个数组,但它的长度因命令行参数而异,所以我以后才知道它是什么。我如何全局初始化数组,但是当我知道长度后我可以更改长度。这是我能做的问题的最简化版本:
#define _XOPEN_SOURCE 500
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
char tile_numbers[1];
void print (void);
int main (void)
{
int x = 7;
char tile_numbers[x];
tile_numbers[0] = 'h';
tile_numbers[1] = 'e';
tile_numbers[2] = 'l';
tile_numbers[3] = 'l';
tile_numbers[4] = 'o';
tile_numbers[5] = '!';
print();
}
void print (void)
{
for(int i = 0; i < 10 ; i++)
{
printf("char: %c", tile_numbers[i]);
}
}
您可以使用 malloc()
动态分配内存,而不是数组。假设在 运行 时,您将数组的大小存储在 int
变量 n
中。然后,您可以使用
char *tile_numbers = (char*)malloc(sizeof(char)*n);
然后,您可以像以前一样为内存位置编制索引,如 tile_numbers[i]
用于 0
到 n-1
范围内的任何 i
。
如果需要全局声明,将声明和赋值分开。在全球范围内,使用
char *tile_numbers;
在获取尺寸的函数中,
tile_numbers = (char*)malloc(sizeof(char)*n);
此外,如果需要调整内存大小,可以使用realloc()
,
tile_numbers = (char*)realloc(tile_numbers,new_size);
不要使用全局 - 在main
(或最初分配的任何地方)定义数组,然后将其作为参数传递给函数需要使用它:
void print( size_t size, const char *arr)
{
for ( size_t i = 0; i < size; i++ )
printf( "char: %c\n", arr[i] );
}
int main( int argc, char **argv )
{
// define tileNumbers here -- we'll get into details below
print( arraySize, tileNumbers );
return 0;
}
不要养成使用全局(文件范围)变量的习惯 - 它会导致代码难以维护和扩展。 有时这是有道理的,但你还不知道那些时间是什么时候。通常,函数应该只通过参数或 return 值共享信息;他们不应该共享全局状态。
因为直到运行时才知道 tileNumbers
需要多大,所以不能将其分配为固定大小的数组并在以后调整大小。在知道大小之前,您需要推迟数组的定义。
在 C99 之前,您唯一的选择是使用动态内存(即 malloc
或 calloc
):
#include <stdlib.h> // for malloc declaration
...
size_t arraySize = getArraySize( ); // where getArraySize is a stand in for any code that sets arraySize
char *tileNumbers = malloc( sizeof *tileNumbers * arraySize );
if ( tileNumbers )
{
// code to initialize tileNumbers goes here
print( arraySize, tileNumbers );
// deallocate memory when we're done with it
free( tileNumbers );
}
从 C99 开始,您可以使用所谓的 可变长度数组 (VLA)。 VLA 的行为主要 类似于常规的固定长度数组,但由于其大小直到运行时才知道,因此不能在文件范围内声明(不能将其用作global), 不能是 struct
或 union
类型的成员,并且在其声明中不能有初始化器。
size_t arraySize = getArraySize( ); // where getArraySize is a stand in for any code that sets arraySize;
char tileNumbers[arraySize];
// code to initialize tileNumbers goes here
print( arraySize, tileNumbers );
无论如何,print
的原型将保持不变。在第一种情况下,我们传递一个指针。在第二种情况下,我们传递一个数组表达式,在计算时 decays 到一个指针表达式。