【问题标题】:Dereferencing a pointer to pointer to pointer etc.. in C language在 C 语言中取消引用指向指针等的指针的指针
【发布时间】:2019-06-06 23:50:43
【问题描述】:

我学校的任务如下:

创建一个函数,该函数将******str作为参数,指向指向指针的指针,指向指向char的指针的指针,并将Follow the white rabbit!设置为char的指针。

void mx_deref_pointer(char ******str);

我是 C 新手并且非常困惑,尽管我已经学会了我能找到的关于指针的一切..(

我想出了以下代码:

#include <stdio.h>
#include <stddef.h>

void mx_deref_pointer(char ******str) {
    char *pstr1, **pstr2, ***pstr3, ****pstr4, *****pstr5;
    str = &pstr5;
    pstr5 = &pstr4;
    pstr4 = &pstr3;
    pstr3 = &pstr2;
    pstr2 = &pstr1;
    pstr1 = "Follow the white rabbit!";
    printf("%s", pstr1);
}

int main() {
    char ******pstr6 = NULL;
    mx_deref_pointer(pstr6);
}

它确实输出 Follow the white rabbit,但我认为它不正确,因为注释掉大部分函数仍然会产生相同的结果。另外,我不知道如何将 NULL 以外的任何内容传递给 mx_deref_pointer()。一些和我一起学习的人想出了一个不同的 mx_deref_pointer:

void mx_deref_pointer(char ******str) {
    str [0] [0] [0] [0] [0] [0] = "Follow the white rabbit!";
}

它似乎有效,但是他们都无法向我解释它是如何工作的。如果有人可以为此提供一段适当的代码,我将非常感激,更重要的是,解释它的作用和方式!

谢谢。

【问题讨论】:

  • str = &amp;pstr5 不会做任何有用的事情,因为 C 通过值传递所有参数。我建议您搜索一下在 C 中模拟通过引用传递
  • 所有这些指针都属于main,只有埋得最深的那个应该(按地址)发送到mx_deref_pointer,在那里它被完全取消引用以设置请求的值。
  • 是的,你的代码本质上是char *pstr1 = "..."; printf("%s", pstr1); 我希望你会得到main 中初始化pstr6 的代码。所以我不清楚你是否完整地提出了这个问题。
  • @Kali,见:stackoverflow.com/questions/23963269/…>

标签: c pointers


【解决方案1】:

为了符合函数的参数(指向char 的 6x 指针),指向 char 的 5x 指针的地址可以是调用者提供的参数(或指向 char 的 6x 指针的值,你重新选择,只要他们指的是有效数据)。因此,您拥有的所有堆栈指针都属于调用者 (main),而不是函数。简而言之,函数和main 应该是这样的:

#include <stdio.h>

void mx_deref_pointer(char ******str)
{
    static char msg[] = "Follow the white rabbit!";
    *****str = msg;
}

int main() 
{
    char *ptr1 = NULL;
    char **ptr2 = &ptr1;
    char ***ptr3 = &ptr2;
    char ****ptr4 = &ptr3;
    char *****ptr5 = &ptr4;

    mx_deref_pointer(&ptr5);

    puts(ptr1);
    return 0;
}

输出

Follow the white rabbit!

请注意,为了避免无意的未定义行为,赋值保存了包含字符串的非常量缓冲区的基地址。从技术上讲,您的编译器必须允许这样做:

void mx_deref_pointer(char ******str)
{
    *****str = "Follow the white rabbit!";
}

但是这样做是不好的做法,因为调用者可能期望一个可修改的字符串。字符串文字不可写,将其存储在char * 中将允许代码写入该字符串,而编译器不会发出任何警告。所以最好在返回之前将字面量复制到可写数组中。

关于数组语法解引用链是如何工作的,给定一些非空类型指针p,这些是等价的:

p[n] == *(p+n)

因此它们是等价的:

p[0] == *(p+0)

但是*(p+0) 就是*p。因此:

void mx_deref_pointer(char ******str)
{
    static char msg[] = "Follow the white rabbit!";
    *****str = msg;
}

等价于:

void mx_deref_pointer(char ******str)
{
    static char msg[] = "Follow the white rabbit!";
    str[0][0][0][0][0] = msg;
}

【讨论】:

  • 现在解释0[p]... :-P
  • @NikosC。已经在这里解释了:With arrays, why is it the case that a[5] == 5[a]?
  • 你是最棒的!!感谢您花时间写这么详细的东西
  • @Kali 请注意,函数中的msgstatic 是有原因的。我把发现原因留给你研究。很高兴它有帮助。
  • 我的印象是,从技术上讲,编译器必须接受char *str = "hello";,正如this question 中所讨论的那样。
【解决方案2】:

【讨论】:

  • 我能改写str [0] [0] [0] [0] [0] [0] = "跟着白兔!";用 & 和 * 表示法?如果是这样,你知道怎么做吗?
  • @Kali 那就是******str = "Follow the white rabbit!"; 因为x[0]*x 相同,那么x[0][0]**x 相同,以此类推。
猜你喜欢
  • 2011-12-10
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 2021-08-14
相关资源
最近更新 更多