【问题标题】:Understanding C: Pointers and Structs理解 C:指针和结构
【发布时间】:2011-02-28 22:48:15
【问题描述】:

我试图更好地理解 c,但我很难理解在哪里使用 * 和 & 字符。通常只是结构。下面是一段代码:

void word_not(lc3_word_t *R, lc3_word_t A) {
    int *ptr;
    *ptr = &R;
    &ptr[0] = 1;
    printf("this is R at spot 0: %d", ptr[0]);
}  

lc3_word_t 是这样定义的结构:

struct lc3_word_t__ {
  BIT b15;
  BIT b14;
  BIT b13;
  BIT b12;
  BIT b11;
  BIT b10;
  BIT b9;
  BIT b8;
  BIT b7;
  BIT b6;
  BIT b5;
  BIT b4;
  BIT b3;
  BIT b2;
  BIT b1;
  BIT b0;
};

这段代码没有做任何事情,它可以编译,但是一旦我运行它,我就会收到“分段错误”错误。我只是想了解如何读取和写入结构以及使用指针。谢谢:)


新代码:

void word_not(lc3_word_t *R, lc3_word_t A) {
    int* ptr;
    ptr = &R;
    ptr->b0 = 1;
    printf("this is: %d", ptr->b0);
}

【问题讨论】:

  • 当您在参数 R 中添加星号时,我认为您希望 *ptr = &R; 成为 ptr = R; 实际上只是一个 [整数] 地址。参数 R 的类型可以被认为是元数据,用于在取消引用对象时适当地访问它。在该地址上使用星号(当它不在声明中时)取消引用该地址并找到它“指向”的内容。
  • 他可能还希望 &ptr[0] = 1; 成为 *ptr = 1; - 希望这是一台 16 位机器...

标签: c pointers data-structures


【解决方案1】:

这里是指针的简要说明(至少在我使用它们时):

int i;
int* p; //I declare pointers with the asterisk next to the type, not the name;
        //it's not conventional, but int* seems like the full data type to me.

i = 17; //i now holds the value 17 (obviously)
p = &i; //p now holds the address of i (&x gives you the address of x)
*p = 3; //the thing pointed to by p (in our case, i) now holds the value 3
        //the *x operator is sort of the reverse of the &x operator
printf("%i\n", i); //this will print 3, cause we changed the value of i (via *p)

并与结构配对:

typedef struct
{
    unsigned char a;
    unsigned char r;
    unsigned char g;
    unsigned char b;
} Color;

Color c;
Color* p;

p = &c;     //just like the last code
p->g = 255; //set the 'g' member of the struct to 255
            //this works because the compiler knows that Color* p points to a Color
            //note that we don't use p[x] to get at the members - that's for arrays

最后,使用数组:

int a[] = {1, 2, 7, 4};
int* p;

p = a;    //note the lack of the & (address of) operator
          //we don't need it, as arrays behave like pointers internally
          //alternatively, "p = &a[0];" would have given the same result

p[2] = 3; //set that seven back to what it should be
          //note the lack of the * (dereference) operator
          //we don't need it, as the [] operator dereferences for us
          //alternatively, we could have used "*(p+2) = 3;"

希望这可以解决一些问题 - 如果有任何我遗漏的内容,请随时询问更多详细信息。干杯!

【讨论】:

  • 太棒了!非常感谢帮忙。所以这是我的下一个问题,我已经修改了我的代码,使其看起来像 - 我将在我的帖子中放入什么,因为显然我无法将代码放入 cmets。但我还是没做对。
  • 我得到的错误是:logic.c:26: error: invalid type argument of ‘->’
【解决方案2】:

我认为您正在寻找有关 C 的一般教程(其中有很多)。只需检查谷歌。以下网站提供了很好的信息,可以更好地解释您的问题。

http://www.cplusplus.com/doc/tutorial/pointers/
http://www.cplusplus.com/doc/tutorial/structures/

它们将帮助您了解基本语法并了解运算符是什么以及它们如何工作。请注意,该站点是 C++,但基本的 C 语言相同。

【讨论】:

  • 好吧,如果您远离 C++ 引用参数并记住在声明 struct 变量时执行 typdef 或使用 struct 关键字,则基本相同。
【解决方案3】:

首先,您的第二行应该给您一些关于将指针转换为 int 的警告。我很惊讶的第三行完全编译。以最高警告级别编译,并注意警告。

* 会根据它是在声明中还是在表达式中做不同的事情。在声明中(如 int *ptrlc3_word_t *R),它仅表示“这是一个指针”。

在表达式(如*ptr = &R)中,它意味着取消引用指针,这基本上是像使用常规变量一样使用指向的值。

& 的意思是“获取此地址”。如果某物不是指针,则使用它将其转换为指针。如果某个东西已经是一个指针(比如你的函数中的Rptr),你不需要再次获取它的地址。

【讨论】:

    【解决方案4】:
    int *ptr;
    *ptr = &R;
    

    这里ptr 没有初始化。它可以指向任何东西。然后用* 取消对它的引用,并为其分配R 的地址。这不应该编译,因为&R 的类型为lc3_word_t**(指向指针的指针),而*ptr 的类型为int

    &ptr[0] = 1; 也不合法。在这里,您获取ptr[0] 的地址并尝试将其分配为1。这也是非法的,因为它是一个右值,但您可以认为您无法更改变量ptr[0] 的位置,因为您本质上是尝试做的是更改ptr[0]的地址。

    【讨论】:

      【解决方案5】:

      让我们单步执行代码。

      首先声明一个指向 int 的指针:int *ptr。顺便说一句,我喜欢这样写int* ptr*int 旁边而不是ptr)来提醒自己指针是类型的一部分,即ptr 的类型是指向的指针int.

      接下来将ptr指向的值赋给R的地址。 * 取消引用指针(获取指向的值),& 给出地址。这是你的问题。你混淆了类型。将 R (lc3_word_t**) 的地址分配给 *ptr (int) 将不起作用。

      接下来是&ptr[0] = 1;。这也没有多大意义。 &ptr[0] 是 ptr 的第一个元素的地址(作为一个数组)。我猜你只想要第一个地址的值,即ptr[0]*ptr

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 2019-10-02
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        相关资源
        最近更新 更多