简体   繁体   English

指向结构的指针在传递给 function 时根本没有变化

[英]Pointer to structure NOT changing at all when passed to function

stack.h堆栈.h

 #define MAX_STACK 10
 typedef int STACK_ITEM;
 typedef struct Stack *STACK ;

stack.c堆栈.c

 #include"stack.h"

struct Stack{
    STACK_ITEM contents[MAX_STACK];
    int tos;
};

_Bool create_stack(STACK s){
    s = malloc(sizeof(struct Stack));
    if(s == NULL )
        return 0;
    s->tos = 0;
    return 1;
}

When calling the create_stack function, it doesn't affect s (pointer to structure) at all.调用create_stack function 时,根本不影响s (指向结构的指针)。 So, my question is: why is s not changing, even though it is a pointer, not a value, passed?所以,我的问题是:为什么s没有改变,即使它是一个指针,而不是一个值,传递?

Function parameters are its local variables. Function 参数是它的局部变量。 That is the parameters hold copies of the passed arguments.也就是说,参数保存传递的 arguments 的副本。 To change an original argument in a function you have to pass it by reference through pointer.要更改 function 中的原始参数,您必须通过指针通过引用传递它。

So change the function like所以改变 function 之类的

_Bool create_stack(STACK *s){
    *s = malloc(sizeof(struct Stack));
    if(*s == NULL )
        return 0;
    ( *s )->tos = 0;
    return 1;
}

In order for a C function to modify an argument, the argument must be given as a pointer to the value to be changed.为了让C function 修改参数,必须将参数作为指向要更改的值的指针给出。 Thus, for a simple integer argument:因此,对于一个简单的 integer 参数:

void Inc(int *value) {
    ++(*value);
}

will do the trick, but:会成功的,但是:

void Inc(int value) {
    ++value;
}

will do absolutely nothing to any argument given in a call to Inc , as the function just gets a copy of the 'value' given.对调用Inc时给出的任何参数绝对不会做任何事情,因为 function 只是获取给定“值”的副本。

The same goes for a pointer!指针也是如此! Your function just changes a copy of the pointer it is passed.您的 function 只是更改了它传递的指针的副本 So, you should change your function to take a pointer to the pointer:因此,您应该更改 function 以获取指向指针的指针:

_Bool create_stack(STACK *s){ // Pointer to a pointer to Stack
    *s = malloc(sizeof(struct Stack)); // Change the value of the STACK object pointed to
    if (*s == NULL )
        return 0;
    (*s)->tos = 0; // And, again, we need to (singly) dereference to 'double' pointer
    return 1;
}

Then, in your calling code, where you originally have something like:然后,在您的调用代码中,您最初有以下内容:

_Bool answer = create_stack(myStackPointer);

you would need to add the address of your pointer:您需要添加指针的地址:

_Bool answer = create_stack(&myStackPointer);

Feel free to ask for further clarification and/or explanation.随时要求进一步澄清和/或解释。

Remember, all parameters are passed by value in C.请记住,所有参数都在 C 中按值传递。

When you pass a pointer as a function parameter, you can access the object (or array of objects) pointed to by that pointer.当您将指针作为 function 参数传递时,您可以访问该指针指向的 object(或对象数组)。

Your create_stack() is passed a pointer to a struct Stack , that is the s parameter.您的create_stack()传递了一个指向struct Stack的指针,即s参数。 It then ignores the original value of s and reassigns it.然后它忽略s的原始值并重新分配它。 That is allowed, but note that it does not change the original pointer in the caller of create_stack() because function parameters are passed by value .这是允许的,但请注意,它不会更改create_stack()调用者中的原始指针,因为 function 参数是按值传递的

There are two ways to do what you want.有两种方法可以做你想做的事。

The first way is to pass a pointer to a pointer:第一种方法是将指针传递给指针:

_Bool create_stack(STACK *s){
    *s = malloc(sizeof(struct Stack));
    if(*s == NULL )
        return 0;
    (*s)->tos = 0;
    return 1;
}

Call it eg:称它为例如:

STACK mystack;
_Bool ret;

ret = create_stack(&mystack);
if (!ret) {
    /* error */
}

The second way is to not pass anything and return a pointer to the allocated stack:第二种方法是不传递任何东西并返回一个指向已分配堆栈的指针:

STACK create_stack(void){
    STACK s = malloc(sizeof(struct Stack));
    if(s != NULL ) {
        s->tos = 0;
    }
    return s;
}

Call it eg:称它为例如:

STACK s;

s = create_stack();
if (s == NULL) {
    /* error */
}

Finally, as a point of programming style, do not typedef pointers in the way you have done.最后,作为编程风格的一点,不要typedef你所做的那样对指针进行类型定义。 It is clearer if the pointer is explicit, for example, use typedef struct Stack STACK;如果指针是显式的就更清楚了,例如使用typedef struct Stack STACK; instead of typedef struct Stack *STACK;而不是typedef struct Stack *STACK; and adjust the usage accordingly, for example, replacing STACK s with STACK *s and replacing STACK *s with STACK **s .并相应地调整用法,例如,将STACK s替换为STACK *s并将STACK *s替换为STACK **s

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

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