简体   繁体   English

使用C实现堆栈获取错误:是一个指针; 您是要使用'->'吗?

[英]implement stack using C getting error : is a pointer; did you mean to use ‘->’?

I'm trying to implement a stack to solve parenthesis problem, but i'm getting confused with the pointers(i'm new to C) here is my code so far: 我正在尝试实现一个堆栈来解决括号问题,但是我对指针感到困惑(我是C的新手),到目前为止,这是我的代码:

typedef struct node{
    char data;
    struct node *next;
}node;
typedef struct stack{
    struct node **head;
}stack;
void push(stack *s, char c){
    node *n = (node *)malloc(sizeof(node));
    n->data = c;
    if(*s->head == NULL){
        n->next = *s->head;
        *s->head = n;
    }
    else{
        n->next = *s->head;
        *s->head = n;
    }
}
void pop(stack *s){
    if(s->head->next == NULL){
        *s->head = NULL;
    }
    else{
        node *temp = *s->head;
        *s->head = s->head->next;
        free(temp);
    }
}
bool isStringBalanced(char** sentence, int size){
    stack *s = malloc(sizeof(stack));
    *s->head = NULL;
    for(int i = 0; i < size; i++){
        int j = 0;
        while(sentence[i][j] != '\0'){
            switch(sentence[i][j]){
                case '(' : push(s, '('); break;
                case '[' : push(s, '['); break;
                case '{' : push(s, '{'); break;
                case ')' : 
                    if(*s->head)
                        if(*s->head->data == '(')
                            pop(s);
                        else return false;
                    else return false;
                    break;
                case ']' :
                    if(*s->head)
                        if(*s->head->data == '[')
                            pop(s);
                        else return false;
                    else return false;
                    break;
                case '}' :
                    if(*s->head)
                        if(*s->head->data == '{')
                            pop(s);
                        else return false;
                    else return false;
                    break;
            }
            j++;
        }
    }
    if(!s->head)
        return true;
    else
        return false;
}

when i try to run this, i get error on all the double arrows like s->head->data and s->head->next Help me to understand how to use right double pointer thanks. 当我尝试运行此命令时,我在所有双箭头(例如s-> head-> data和s-> head-> next)上均遇到错误帮助我了解如何使用正确的双指针谢谢。

A double pointer is a pointer to a pointer. 双指针是指向指针的指针。 It is useful for example when you want that a function changes where a pointer is pointing: 例如,当您希望函数更改指针所指向的位置时,这很有用:

void foo(char **str)
{
    *str = "World";
}

void bar(void)
{
    const char *x = "Hello";
    puts(x); // points to "Hello"
    foo(&x);
    puts(x); // points to "World"
}

This would print 1 : 这将打印1

World
Hello

A double pointer can be used for storing an array of arrays or pointers. 双指针可用于存储数组数组或指针。 This can be used for example for storing matrices. 例如,这可用于存储矩阵。

In your case, the double pointer in stack is not needed, it's inside an structure. 在您的情况下,不需要stack的双指针,它在结构内部。 Sure you can declare it as a double pointer, but it will make live unnecessarily harder. 当然,您可以将其声明为双指针,但这会使生存变得不必要地困难。 head is already inside a struct and you usually pass the stack object as whole. head已经在结构内部,并且通常将整个stack对象传递。 So functions altering the pointing location of head can do that without the need of a double pointer, because head is not a variable, it is a member of a struct (see example below). 因此,更改head的指向位置的函数可以做到这一点,而无需使用双指针,因为head不是变量,它是struct的成员(请参见下面的示例)。

So you can rewrite it as: 因此,您可以将其重写为:

typedef struct stack{
    struct node *head;
}stack;

Then the push can be rewritten as: 然后可以push重写为:

int push(stack *s, char c)
{
    node *n = calloc(1, sizeof *n);
    if(n == NULL)
        return 0;

    n->data = c;
    n->next = s->head;
    s->head = n; // see footnote 2
}

As for the question about -> and . 至于->和的问题. : -> and . ->. are used to access the members of a struct. 用于访问结构的成员。 If the variable (or expression) is not a pointer, then you use . 如果变量(或表达式)不是指针,则使用. , if the variable (or expression) is a pointer, then you use -> . ,如果变量(或表达式)是指针,则使用-> It's as simple as that: 就这么简单:

// Note these examples show only how to use -> and .

stack *s;
s->next;             // because s is a pointer
s->next->next;       // because s->next is a pointer
s->next->next->data  // because s->next->next is a pointer

stack s;
s.next;              // because s is not a pointer
s.next->next;        // because s is not a pointer, but s.next is a pointer
s.next->next->data;  // because s is not a pointer, but s.next is a pointer
                     // and s.next->next is also a pointer

fotenotes 脚注

1 A string literal (the ones in quotes) return the address of where the sequence of characters are stored. 1字符串文字(用引号引起来)返回存储字符序列的地址。 In C a string is just a sequence of characters that ends with the '\\0' -terminating byte. 在C语言中,字符串只是一个以'\\0'终止字节结尾的字符序列。

When you do 当你做

const char *x = "Hello";

your are not copying the string to x , you are assigning the location of the sequence 没有将字符串复制到x ,而是分配了序列的位置

base = some memory location

base
+---+---+---+---+---+----+
| H | e | l | l | o | \0 |
+---+---+---+---+---+----+

of char s to the pointer x . char s的指针x The value of x is that address base . x的值是该地址的base

2 Thanks to user user7231 for pointing out that in this case even the if(n->head == NULL) check is not necessary. 2感谢用户user7231指出在这种情况下,甚至不需要if(n->head == NULL)检查。 I've updated my answer using his/hers lines. 我已经用他/她的台词来更新我的答案。 Credit goes to user7231 . 功劳归于user7231

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM