繁体   English   中英

当我在编译时只知道一个维度时,在C中使用2D数组全局变量

[英]Using a 2D array global variable in C when I only know one dimension at compile-time

我的情况很奇怪。 我有一个全局的二维char数组(用于表示字符串数组)。 这些字符串的长度不超过28,包括终止字符,所以我只想使用一个维度设置为28的二维数组。另一个维度是在编译时确定的,但我的程序计算了多少个插槽在分配数组之前需要它。

我试图像这样(全局)声明数组:

char** dictionary;

然后在我的一个函数中,我需要分配它。 一旦我尝试使用字典[0] [0]或其他东西访问它们,这两个给我带来了错误的访问错误:

dictionary = malloc(sizeof(char)*(28)*numberWords); //numberWords ends up being around 60000
//separately:
char newDict[numberWords][28];
dictionary = newDict;

是的,我是C的新手。希望我的学校教我而不是Java。

如果你想对字符串进行全局访问,并且你知道字符串的最大长度但是你不知道在程序执行之前你想要多少个字符串,那么你可以声明一个指向char数组的全局指针[28] ]。 这里的好处还在于内存是连续的。

#define MAX 28

char ( *p_array)[MAX] ;

void func( int size )
{
    p_array = malloc( sizeof( *p_array ) * size ) ;

    for( int i = 0 ; i < size ; i++ )
        snprintf( p_array[i] , sizeof( *p_array ) , "test string no.: %d" , i ) ;

    for( int i = 0 ; i < size ; i++ )
        printf("%s\n" , p_array[i] ) ;
}
char newDict[numberWords][28];
dictionary = newDict;

首先关闭这部分是错误的,newDict是一个数组,它分配在一段内存中,而字典是一个指向指针的指针,它散布在Heap的不同部分,你得到了错误的访问,因为字典正在寻找一个指向指针的指针和newdict不包含指针,读取数组和指针,它们是不同的,虽然它们似乎以类似的方式工作

我看到你想使用数组表示法因此你分配dictionaty = newdict(这是错误的)

easiset这样做的方法是

char ** dictionary;
 dictionary = (char **)malloc(sizeof(char *)*NUMBER_OF_WORDS)

 for(int i =0;i<NUM_WORDS,i++)
 {
 dictionary[i] = (char *)malloc(sizeof(char)*28);
 }

 now you can access each word like this 
 dictionary[word_number][the letter]; 

 //so in your code you said char ** dictionaty, lets go through this, dictionary is a 
   pointer to another pointer that points to a char. look at my code, dictionary is a 
   pointer, that points to another pointer that eventuall points to a char.

这为什么有效?

数组表示法就像这样一个[x] = *(a + x),换句话说转到数组a,添加x并取数字在那个内存位置,方括号称为句法糖,只是为了让我们的生活更轻松,真正发生的是*(a + x)。

对于一个2d数组a [x] [y] = *(*(a + x)+ y)这就是说转到指针a,将x加到指针中取内存中的内容*(a + x)然后将y添加到该内存中并将其指向*(*(a + x)+ y)

请注意当我说添加x到指针时,它取决于数组保持什么,比如你有一个int数组,因为int是4个字节,并且假设x是1,

int a[10]
a[1] = *(a+1) (the compiler actually adds 4 bytes to the address although we 
said 1  obviously since an int is 4 bytes, this 
is pointer arithmetic you should read up on it. this makes things much easier. 

在内存中真正发生的是添加4个字节以转到+ 1的地址,编译器会为我们处理这个问题,所以这会使事情变得更容易,在你的情况下它是一个char,所以说[1] = *(a + 1),

回到你的问题。

dictionary [0] [0]会给你第一个单词中的第一个字母,因为你的字符串是空终止的,所以你用整个字符串得到像printf这样的字符串。

如果你宣布

char newDict[numberWords][28];

那么newDict 不是 char ** ,而是一个实际的二维字符数组,所以赋值不起作用。 另一方面,我认为newDict声明是正确的方法。 如果你真的想要这个全局指针的东西,那么也许就像

typedef char String[28]; //a String is a single array of 28 chars
String* dictionary;

将与你的newDict声明兼容(因为数组到指针衰减仅适用于“外部”级别,而不是递归到所有级别)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM