【问题标题】:Is there a way to bring a pointer that is at the end of an array to the start without knowing size of array?有没有办法在不知道数组大小的情况下将位于数组末尾的指针带到开头?
【发布时间】:2022-01-04 06:07:44
【问题描述】:

给定一个数组,假设char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog"}; 和一个指针char ** point = &word[9];,但不知道输入数组的大小,如何将指针指向数组的开头?这样做的目的是在递归函数中使用,其中指针设置在数组的开头,但随着函数递归,每次递归时指针都会递增。

我尝试简单地递减指针,直到我在开始时碰到一个空指针,但指针指向数组中内存中的某个随机值。关于如何解决这个问题的任何建议?

【问题讨论】:

  • 将幻数 9 存储在一个单独的变量中,就这么简单。

标签: arrays c pointers


【解决方案1】:

一般来说,仅给定一个指向其中一个元素的指针,就无法知道数组的大小;你必须自己跟踪它。

要么保留一个指向数组开头的指针,要么自己在其中放置一些标记值(如 NULL 指针)。

【讨论】:

    【解决方案2】:

    你不能。指针只不过是内存中的一个地址。一个简单的数字。数组的开头在内存中的不同地址,另一个简单的数字。

    例如,您的数组可能从内存地址 12608(= 除 0 之外的任何可能的数字)开始,它的最后一个元素将在地址 12680。您不知道地址 12600 或 12688 存储了什么. 如果您访问这些地址中的任何一个,任何事情都可能发生:静默数据损坏、立即崩溃,甚至包括一些坏人将后门下载到您的 PC 上。

    因此,您的工作是确保您的程序不会越界访问任何数组。您的工作是确保在需要的任何位置都知道数组的大小和起始地址,并确保所有访问都在这些限制范围内。

    现在,对于示例中的静态分配数组,您可以使用 sizeof 运算符获取其大小:

    size_t wordCount = sizeof(words)/sizeof(*words);
    printf("this should be 9 in your example: %zu\n", wordCount);
    

    这将获取用于数组words 的字节数,然后将其除以数组*words 的第一个元素中的字节数。这是获取静态数组元素计数的标准技巧。


    但是,只有当words 实际上是一个编译器知道其大小的数组时,它才有效。一旦将其传递给函数,该信息就消失了:

    void buggy(char* words[]) {
        printf("not what you expect: %zu\n", sizeof(words)/sizeof(*words));
    }
    

    原因是,当您将数组传递给函数时,它们会衰减为指针,而指针只是一个数字,不保留数组的任何大小信息。该信息仅存在于数组的类型中,并且该类型已衰减。

    【讨论】:

    • @EricPostpischil 这就是语言律师的观点。但它既无助于理解,也与编译器为真实物理机器发出的真实机器代码无关。对于当今使用的所有相关 CPU,数据指针只不过是一个简单的数字。
    • 它不是数字并且机器代码不受控制的一个原因是现代编译器不直接生成机器代码。他们从语义上分析源代码并对其进行优化。当指针被视为“简单数字”而不是按照 C 标准规则使用时,它可能会以各种方式导致未定义的行为。告诉学生指针是数字会导致他们的代码出现错误。
    【解决方案3】:

    您可以使用以下方法获取数组的大小:

    printf("length of the array : %d \n", sizeof(words)/8);
    

    请参阅下面的示例。

    int main()
    {
    
      char *words[] = {"The", "Quick", "Brown", "Fox", "Jumped", "Over", "The", "Lazy", "Dog"};
      char ** point = &words[9];
      int i;
      printf("length of the array : %d \n", sizeof(words)/8);
    
      for(i=0;i<9;i++){
        printf("%s\n",words[i]);
      }
    
    
      for(i=0;i<9;i++){
       printf("%d\n",point[i]);
      }
      return 0;
    }
    

    然后,您可以使用数组的大小进行循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 2021-03-26
      • 1970-01-01
      • 2011-05-30
      • 2011-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多