【问题标题】:Error in Accessing two dimensional character array from function in C从 C 中的函数访问二维字符数组时出错
【发布时间】:2020-12-18 16:07:14
【问题描述】:

我看过很多关于在 C 中访问二维数组的在线资源,但都只显示一个答案*( *(arr + i) + j)) 但不幸的是,它给了我这个错误

error: invalid type argument of unary ‘*’ (have ‘int’)
 27 |      printf("%d ",*(*(arr + i) + j));

我的代码:

void pointer_string_array_indexing(char *arr){
        
        for (int i = 0; i < 2; ++i)
        {
            
            for (int j = 0; j < 4; ++j)
        {
            //printf("%c : %d ",*(arr+4*i+j),(arr+4*i+j)); //this will give correct answer
            printf("%c ",*( *(arr + i) + j)); // compilation error
        }
        printf("\n");
        }
        
    }

int main(){
    char S[][4] = {"abc","efg"};
    pointer_string_array_indexing(S);
return 0;

}

我知道这是一个非常有名且重复的问题,但请提供解决方案的代码 sn-p。 我用的是 Ubuntu-20(不过没关系)

【问题讨论】:

  • 请分享其中的一些“许多资源”(以便我们向您展示您在哪里误解了它们)。并分享您的错误。
  • @user3121023 是的,它正在工作,你能否详细说明你的答案为什么它工作以及我的代码哪里做错了?
  • 快速浏览一下,显示来源相互复制。但无论如何,没有一个来源给出如何将二维数组传递给函数的示例,因此您需要更好的来源。
  • *( *(arr + i) + j) 是一种超级复杂的写法arr[i][j]

标签: c pointers multidimensional-array


【解决方案1】:

要了解为什么一种方式有效而另一种方式无效,您必须了解一些关于 C 如何分配字符串和数组的奇怪之处,以及为什么有时字符串是数组而有时它们是指针。

您的数组被声明为char S[][4]S 中的所有字符都在内存中的一个连续块中。当您访问S[i][j] 时,编译后的代码会通过计算ij 表示的偏移量来确定您引用的字符的地址,例如char *indexed_character_address = S + i*4 + j。现在编译后的代码使用indexed_character_address 来加载或存储到,这取决于S[i][j] 的使用方式。

声明字符串数组的另一种非常不同但令人困惑的相似方式是这样的:

char *T[] = { "tuv", "wxyz" };

编译器在后台生成此数组的操作与此非常相似:

const char hidden_tuv[4] = { 't', 'u', 'v', '\0' };
const char hidden_wxyz[5] = { 'w', 'x', 'y', 'z', '\0' };
char *T[2] = { hidden_tuv, hidden_wxyz };

"tuv""wxyz" 字符串首先放置在任意位置,不能保证哪个会先出现,或者它们会彼此靠近。然后使用这两个任意指针创建并初始化另一个数组。

编译器生成的用于访问T[i][j] 的代码的工作方式与S 的工作方式非常不同。首先,它计算Tith 字符串指针的地址,然后从内存中加载字符串的起始地址之一,然后使用j 偏移该地址的起始地址。像这样:

char **address_in_T = T + i;
char *string_start_address = *address_in_T;
// now string_start_address is either hidden_tuv or hidden_wxyz
char *indexed_character_address = string_start_address + j;

那个冗长的代码等价于这个小表达式:

char *indexed_character_address = T[i] + j;
                          //    or &(T[i][j])
                          //    or *(*(T + i) + j)

您的S 变量是一个二维字符数组,用字符串数据初始化,类型为char[2][4]。我的T 变量是一维字符指针数组,类型为(char *)[2]

这里真正令人困惑的部分是,尽管这两个变量的类型非常不同,但 C 语法可以使访问它们看起来非常相似

char c1 = S[i][j];   // actually reads *(S + i*4 + j)
char c2 = T[i][j];    // actually reads *( *(T + i) + j)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    相关资源
    最近更新 更多