0

我这里有这段代码,它给了我编译器错误,我知道这里还有许多其他问题,标题基本完全相同;我已经阅读了其中很多,但我的所有问题都没有得到解答。在过去的几天里,我在 stackoverflow 和教学网站上阅读了很多关于指针和结构的内容,又是几十个,我觉得我只需要在我面前的一个物理示例来剖析和解释。我觉得我知道大部分这些东西,但我对自己的不确定性比我想的要多得多。如果有人可以帮助我了解发生了什么。我在下面发布了一个编号列表,告诉你我认为正在发生的事情,并希望我在很大程度上是对的,更少解释你必须做的事情,哈哈,开个玩笑。那么这里是代码。

struct foo{
    int num;
    char  *word;
    struct foo *ptr;
};

void func1(struct foo*);
void func2(struct foo);

int main() {

    struct foo a;
    a.num = 20;
    a.word = "wordOne";
    func1(&a);
    printf("%d %s", a.num, a.word);       // refer to #3 below.

    a.ptr = &a;
    a.num = 55;
    a.word = "thirdToLastWord";
    func2(a);
    printf("%d %s\n", a.num, a.word);
}

void func1(struct foo *a)
{
    while(*(a->word) != '\0')
        {
            putchar(*(a->word));
            a->word++;
        }
    putchar('\n');
    if(a->num % 10 != 0)
        { a->num *= 2; }
    a->word--;
    printf("num equals %d\n", (*a).num);
}

void func2(struct foo a)
{
    if((*a).num == a->ptr->num)               //compiler error
        {(*a).num = (*((*a).ptr)).num +1; }   //compiler error
    else    {   a->num = 200;   }
    a->word = "wordsix";
    a->ptr->word = "wordseven";
    printf("function 2 %d %s\n", (*a).num, (*((*a).ptr)).word);}
}

好的。所以我想我理解第一个功能。但是,如果我错了,或者我似乎对它为什么这样做有错误的理解,请在以下任何一个方面纠正我。

1)在 main func1 将结构“foo”声明为指针之前。当调用 func1 时,我们传入“a”的地址,这样我们就知道要指向哪个地址。

2) func1 中的所有内容都会改变原来的结构。当在 func1 之外打印出来时,该单词会递减以仅显示最后一个字母“e”。

3) 在我评论#3 的行上,它打印出原始结构 foo 的 .num 而不是指针版本(即使它们是相同的)。

我希望我到目前为止还没有搞砸。

4) 好的,所以 a.ptr = &a 设置 struct var "struct foo *ptr" 在原始 foo 结构中等于 a 的地址;这恰好是指针“struct foo *ptr”所在的确切结构。对吧?

5)我们将他称为(main/orig 结构)的成员,他已经被建立为 main 上方的指针。

6) 那么这是否会在结构中形成一个无限循环,这些结构通过自身内部的指针链接在一起?

我评论编译器错误的地方是我很肯定我遇到问题的地方。

7) 首先,在设置 a.ptr = &a; 之后 我们将带有初始化指针“ptr”的结构副本传递给函数func2,是吗?

8) 在第一个 if stmt 中,看起来我们正在将 a->word 与 a->ptr->num 进行比较。我假设的意思是说:IF {属于“a”指向的结构的成员“word”等于成员“num”,属于指针“ptr”指向的结构和“ptr是再次被指针“a”指向}这似乎是对的,但我不认为它是....

9)如果这是真的,那么下面的行说的是完全相同的事情,加上了+1。

10) 我想最后在 main 中的 printf 打印出 num 和 word 在它们进入 func2 之前是什么,或者 func2 中的某些指针已经改变了它们的值。

我将非常感谢您的所有反馈和建议,我应该如何将这个指针 && 结构 ptr->member 和/或 structure.member 东西根植在我的脑海中。

另外,我不确定这是否出现在我的问题中,但我对双指针也相当不稳定。如果不是太麻烦的话,有人可以告诉我双指针是如何在这里集成到我的代码中的吗?

谢谢

4

2 回答 2

0

a 不是指针。您在很多场合都使用->运算符来访问非指针成员,这会给您带来错误。struct

您的代码中有很多错误。例如,您没有为*word. 但是在其中存储一个值:

a.word = "wordOne";

您应该numa.num.

这是一个关于使用指向结构的指针的教程,它可能会帮助您理解它。

于 2012-04-21T23:59:51.613 回答
0

这段代码确实有很多错误,为了清楚起见,我将尝试浏览您的列表。

1.) 是的,你可以在这里传递一个指针,但是在取消引用指针参数之前有必要检查 NULL。如果您现在养成这样做的习惯,您将节省无数时间来追踪分段错误的来源。

2.)func1不变a->num

if(a->num % 10 != 0)
    { a->num *= 2; }
// a->num % 10 = 20 % 10 = 0, and 0 != 0 is false

此外,Blue Moon 是正确的a->word,这可以通过以下两种方式之一正确完成。

具有全局性:

const char *global = "wordOne";

int main(int argc, char *argv[]) {
  a.work = (char*)global;
  /*...*/
}

或者 Blue Moon 所指的首选方式:

const char *global = "wordOne";

int main(int argc, char *argv[]) {
  size_t sz = sizeof(global);
  a.work = (char*)malloc(sz);
  for(int i = 0; i < sz; i++) { a.work[i] = global[i]; }
  /*...*/
}

注意:使用第二种方法,您最终将需要free()该内存。

多读一点指针,你就会明白为什么

关于func2(),此函数不使用指针参数,因此取消引用它肯定会引发编译错误。

void func2(struct foo);
// struct foo is passed 'by value'

我真的希望这有助于澄清事情!:-)

于 2015-09-16T02:07:40.117 回答