【问题标题】:Global pointer to local pointer array指向局部指针数组的全局指针
【发布时间】:2017-01-02 03:55:24
【问题描述】:

我在一个函数中有一个指向数组的指针数组。我需要在另一个函数中访问该数组。

指针数组

char *ptr[size + 1];

我做了一个全局指针

char *p;

我指向ptr(与ptr在同一个函数中)

p = *ptr;

然后我尝试从另一个函数访问 ptr

void otherFunction(void){
    for(int n = 0; n < 6; n++)
    {
        char* str = &p[n];
        printf("%i %s\n", n, str);
    }
}

ptr[0] = "abcd"
ptr[1] = "bcde"
ptr[2] = "cdef"
ptr[3] = "defg"
ptr[4] = "efgh"
ptr[5] = "fghi"

otherfunction(); 的输出是:

0 abcd
1 bcd
2 cd
3 d
4 
5 

我希望输出是

 0 abcd
 1 bcde
 2 cdef
 3 defg
 4 efgh
 5 fghi

我的问题是:(0)这里出了什么问题。 (1)我该如何解决它(2)或者有更好的方法来做到这一点。要求是 otherfunction() 不能接受任何参数,ptr 需要保持其功能的本地性。 (我确定其他代码不会导致问题,ptr 也没有问题)

【问题讨论】:

  • p = *ptr; dereferences ptr 和说 p = ptr[0]; 相同
  • 你知道你可以传递参数,不是吗?
  • 应该注意,全局指针很少是一个好主意,尤其是当您要将它们指向局部变量时。函数完成后,堆栈将被清理,然后您将获得未定义的行为。
  • @Goodies 这只是一个简单的场景,这将是一个坏主意,全局指针几乎在任何情况下都不好。此外,除了使用全局变量之外,总有一种解决方案,它们总是比使用全局变量更好的解决方案,所以我建议尽可能避免使用全局变量,即使它听起来太激烈了。当然,这个评论主要是针对 OP 的。
  • @Goodies p = ptr; 会出错

标签: c arrays pointers


【解决方案1】:

ptr 是一个指针数组。

char **p = ptr;

char *str = p[n];
printf("%i %s\n", n, str);

【讨论】:

  • p有什么用?为什么不干脆做char* str = ptr[n];
  • @Lundin 我不知道,请咨询 OP。也许p 是全局的,但不是ptr。这个答案只是一个快速的答案,并不详尽,因此我已经对另外两个投了赞成票。
  • 这就是重点。 OP 很可能不应该以“全局指针”开头。
【解决方案2】:

char *ptr[size + 1];

char* p = *ptr;

char* str = &amp;p[n];

这使 p 指向字符串数组ptr 的第一个字符串,然后str 将逐个字符地遍历该字符串。我认为你的意思是这样的:

char** p = ptr; // p points to the first string of ptr
...
char* str = p[n]; // str points to the nth string of ptr

除此之外,使用全局指针并不是一个好主意。可能更好的方法是将ptr 本身传递给函数otherFunction,该函数将具有原型:

void otherFunction(char** p);

你用ptr调用它:

otherFunction(ptr);

【讨论】:

    【解决方案3】:

    (0) 这里出了什么问题。 (1)我该如何解决(2)或者有更好的方法来做到这一点

    (0) 整个程序设计。使用像这样的全局变量——尤其是指针——是意大利面条式编程的一种形式,应该避免。您正在程序中各种不相关的部分之间创建紧密的耦合和依赖关系。

    一般来说,指针指向指针的存在通常表明设计不佳。指针对指针有一些有效用途,例如通过函数参数返回修改后的指针等特殊情况。在您的情况下没有明显的理由使用它们。

    (1) 通过使用几个类型限定符和存储说明符来减少那些混乱的全局变量的范围。相反,通过 setter/getter 函数访问指针数组。

    (2) 是的,把程序改成如下代码:

    static const char* ptr [] =
    {
      "abcd",
      "bcde",
      "cdef",
      "defg",
      "efgh",
      "fghi",
      NULL
    };
    
    inline const char* get_str (size_t index)
    {
      return ptr[index];
    }
    
    inline void set_str (size_t index, const char* str)
    {
      ptr[index] = str;
    }
    

    【讨论】:

    • “一般来说,指针指向指针的存在通常表明设计不佳。”那么int main(int, char **); 是一个糟糕的设计吗?这真的很严格。除此以外,我完全同意您的所有回答。 3星程序员必须受到惩罚,我同意但是,两个开始?在很多情况下它们是有效的。
    • @Stargateur char** argv 严格来说不是 main 的有效形式,但 char* argv[] 当然会衰减为指针,因此它们是等价的。两颗星的存在意味着您正在做一些与众不同的事情,例如通过参数返回指向 malloc:ed 数据的指针 - 这非常好。根据我的经验,在其他情况下使用指针对指针通常是程序员混淆的结果。例如错误地使用char** ptr = malloc(n*sizeof(*ptr)), 分配“二维数组”。
    • 然而,在动态分配指针数组时使用指针到指针会很好 - 尽管在这种情况下使用数组指针会更正确。如果您真的知道自己在做什么,那么指针对指针非常好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2021-11-11
    相关资源
    最近更新 更多