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

时间:2013-12-30 05:21:10

标签: c arrays variables 2d global

我的情况很奇怪。我有一个全局的二维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。

3 个答案:

答案 0 :(得分:1)

如果你想对字符串进行全局访问,并且你知道字符串的最大长度,但是你不知道在程序执行之前你想要多少个字符串,那么你可以声明一个指向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] ) ;
}

答案 1 :(得分:1)

char newDict[numberWords][28];
dictionary = newDict;

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

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

easyiset方法是

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]会给你第一个单词中的第一个字母,因为你的字符串是空终止的,所以用%s得到整个字符串就像printf一样。

答案 2 :(得分:0)

如果您声明

char newDict[numberWords][28];

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

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

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