【问题标题】:Syntax of pointers to structures - linked lists结构指针的语法 - 链表
【发布时间】:2017-03-23 21:52:25
【问题描述】:

我学习电子工程,并且正在学习 C 作为我的第一语言。我一直在学习 IIT C 编程课程,当涉及到指针时,我通常需要多一点时间来理解程序。

我现在正在学习链表,我会放一部分代码,然后告诉大家我遇到了什么问题。我不会把所有东西都放上去,因为我认为没有必要。

typedef struct node_type {
    int data;
    struct node_type *next;
} node;

typedef node_type *list;

list head, temp;
char ch;
int n;
head = NULL;
scanf("%c", &ch);

while (ch == 'Y' || ch == 'y') {
    temp = (list)malloc(sizeof(node));
    temp->data = n;
    temp->next = head;
    head = temp;
    scanf("%c", &ch);

我不明白为什么在处理指向结构的指针时使用'->',我现在知道temp->data = n; 等同于(*temp).data = n;。但是我对第二个表达式的语法有疑问,为什么使用它可以访问“temp”指向的结构内的“数据”。

当声明变量时,这里有一个顺序:http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

我知道运算符有优先顺序。在声明中,我将 * 读作“指向”。我应该如何阅读代码中间的(*temp).data(不是声明)?

在课程开始时,Dr.P.P.Chakraborty 说 * 可以理解为“the content of”,但在这个表达中就没有意义了:“the content of temp...”

  • 在声明中不使用运算符 * 是什么意思?
  • typedef 的使用遵循与int *a[] 一样的声明规则? typedef int *a[] 声明类型“a”是指向 int 的指针数组?

感谢任何帮助。

【问题讨论】:

  • 听起来您有多个问题。你能用项目符号列表列出所有问题吗?
  • 是的,也许它会在未来对某人有所帮助。现在我想我明白意思了,但我会调整我的问题。谢谢。
  • 如果您使用的是 C 编译器而不是 C++ 编译器,并且没有其他头文件定义结构,那么 typedef node_type *list; 将无法编译。你可以使用typedef struct node_type *list;(但you shouldn't typedef pointers),这样就可以编译了。
  • (*temp).data读成tyro的写法temp->data——对代码的轻微混淆。
  • typedef node_type *list;不要将指针隐藏在 typedef 后面。它会让你和其他人感到困惑。只是不要。

标签: c pointers syntax


【解决方案1】:

*temp 表示指针取消引用。因此,当您编写 (*temp).data 时,(*temp) 的结果类型为 node 而不是 node*。因此您可以使用.访问结构字段

【讨论】:

  • temp 是一个指针,取消引用意味着可以访问 temp 指向的内容?如果这是正确的,也许最好忘记“内容”......
  • @JoãoPedro,更准确地说是“...所指向的内存内容”。
  • 您也可能会看到符号 temp->data 相当于 (*temp).data 并且都取消引用指针 temp 以定位存储在那里的结构,然后检索数据的值。
【解决方案2】:

我知道运算符有优先顺序。在声明中,我将 * 读作“指向”。我应该如何阅读代码中间的 (*temp).data(不是声明)?

“检索temp 指向的struct node_type 实例的data 成员”。

图形化:

      +---+        +---+
temp: |   |----->  |   | data <--- I want this
      +---+        +---+
                   |   | next
                   +---+

但是我对第二个表达式的语法有疑问,为什么使用它可以访问“temp”指向的结构内的“数据”。

表达式temp 的类型为“指向struct node_type 的指针”。一元* 操作符dereferences 访问指向对象的指针。因此,表达式 *temp 的类型为struct node_type

假设以下声明:

struct node_type instance;
struct node_type *pointer = &instance;

两个声明完成后,以下表达式为真:

 pointer == &instance;    // struct node_type * == struct node_type *
*pointer ==  instance;    // struct node_type   == struct node_type

 pointer->data == (*pointer).data == instance.data; // int == int == int
 pointer->next == (*pointer).next == instance.next; // struct node_type * == struct node_type *

成员选择运算符.-&gt; 都与后缀运算符分组,后者的优先级高于一元* - 如果您编写*temp.data,编译器会将其解析为*(temp.data) ,这意味着“我想要temp.data 指向的东西。”

图形化:

      +---+              +---+
temp: |   | data ------> |   | <--- I want this
      +---+              +---+
      |   | next
      +---+

在这种特殊情况下,这不是您想要的。

如您所见,temp-&gt;data 等效于 (*temp).data - -&gt; 运算符隐式 取消引用 temp 指针。在处理指向structunion 类型的指针时,你真的想使用-&gt; - 它不那么刺眼,而且你不太可能犯错。

其他需要注意指针优先级问题的地方:

T *a[N];   // a is an N-element array of pointers to T

图形化:

   +---+            +---+
a: |   | a[0] ----> |   | some instance of T
   +---+            +---+
   |   | a[1] --+
   +---+        |   +---+
    ...         +-> |   | some other instance of T
                    +---+

每个a[i] 都指向一个T 类型的不同对象。要访问该对象,您需要取消引用数组元素 - *a[i]

T (*a)[N]; // a is a pointer to an N-element array of T

图形化:

   +---+        +---+
a: |   | -----> |   | (*a)[0]
   +---+        +---+
                |   | (*a)[1]
                +---+
                 ---

要访问数组的元素,您需要在应用下标之前尊重指针a - 您想要索引a 的东西指向,所以你需要写(*a)[i]

T *f();   // f is a function returning a pointer to T

函数f返回一个指针值;要访问被指向的东西,您需要尊重返回值:

x = *f();

请注意,这是很少完成的;您总是希望对返回的指针值进行完整性检查。你更有可能看到:

T *p = f();
if ( p )
  x = *p;

最后,

T (*f)(); // f is a pointer to a function returning T

f 指向一个函数 - 您必须取消引用 f 本身才能执行该函数:

x = (*f)();

您可以根据其声明了解如何使用af 的每个版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-25
    • 2013-02-13
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2015-03-22
    相关资源
    最近更新 更多