C语言指针内存分配相关问题,求大神指导。。。

这里有两段程序,基本上是一样的。都是使用链表来实现队列。这里实现了出队和入队操作。第一段程序能够正确执行,但是第二段程序不可以,原因是rear和front总是相同的,所以输出的都是-1。我检查了一下,发现每一次rear改变会是的front同时改变。这是为什么?第一段程序通过一个结构体传递rear和front确可以,这是为什么?是通过结构体构建了二级指针吗?求大牛。。。我都快绕晕了,好几次遇到这个问题了。。。

能够正确执行的程序:

 #include<stdio.h>
#include<stdlib.h>

typedef struct Node
{
        int data;
        struct Node *next;
}Node;

typedef struct Q
{
        Node *front;
        Node *rear;
}Q;

void push(Q*q, int e)
{
        Node *node = (Node*)malloc(sizeof(Node));       //分配空间
        node->data = e;     //数据域
        node->next = NULL;  //指针域
        q->rear->next = node;   //添加到末尾
        q->rear = node;     //更新尾指针
}

int pop(Q* q)
{
        if (q->front == q->rear)
            return -1;
        Node *t = q->front->next;       //获取队首元素
        int e = t->data;        //获取队首数据域
        q->front->next = t->next;       //更新队首指针
        if (t == q->front)  //如果队首与队尾相同,则将队尾指针指向队首
            q->rear = q->front;
        free(t);        //释放
        return e;       //返回队首数据域
}


int main()
{
        Q queue;
        queue.rear = (Node*)malloc(sizeof(Node));
        queue.front = queue.rear;
        push(&queue, 1);
        push(&queue, 2);
        push(&queue, 3);
        int k = pop(&queue);
        printf("%d\n", k);
        k = pop(&queue);
        printf("%d\n", k);
        k = pop(&queue);
        printf("%d\n", k);
        return 0;
}

不能够正确执行的:

#include<stdio.h>
#include<stdlib.h>

typedef struct Node
{
        int data;
        struct Node *next;
}Node;

void push(Node* rear, int e)
{
        Node *node = (Node*)malloc(sizeof(Node));       //分配空间
        node->data = e;     //数据域
        node->next = NULL;  //指针域
        rear->next = node;  //添加到末尾
        rear = node;        //更新尾指针
}

int pop(Node* rear, Node* front)
{
        if (front == rear)
            return -1;
        Node *t = front->next;      //获取队首元素
        int e = t->data;        //获取队首数据域
        front->next = t->next;      //更新队首指针
        if (t == front) //如果队首与队尾相同,则将队尾指针指向队首
            rear = front;
        free(t);        //释放
        return e;       //返回队首数据域
}


int main()
{
    Node *rear = (Node*)malloc(sizeof(Node));
        Node *front = rear;
        push(rear, 1);
        push(rear, 2);
        push(rear, 3);
        int k = pop(rear,front);
        printf("%d\n", k);
        k = pop(rear, front);
        printf("%d\n", k);
        k = pop(rear, front);
        printf("%d\n", k);
        return 0;
}


因为 你传的是一个 形参变量 还记得 交换两个数的经典代码么, 为什么 只传 变量不可以修改值 原因是一样的!但是第二段程序不可以,原因是rear和front总是相同的,所以输出的都是-1。我检查了一下,发现每一次rear改变会是的front同时改变。这是为什么?你说的这几句话,其实指针的值是不会变得,和交换两个数的原理是一样的,其实修改很简单,可以直接用引用我贴下我的代码!

#include
#include

typedef struct Node
{
int data;
struct Node *next;
}Node;

void push(Node* &rear, int e)
{
Node node = (Node)malloc(sizeof(Node)); //分配空间
node->data = e; //数据域
node->next = NULL; //指针域
rear->next = node; //添加到末尾
rear = node; //更新尾指针
}

int pop(Node* &rear, Node* front)
{
if (front == rear)
return -1;
Node *t = front->next; //获取队首元素
int e = t->data; //获取队首数据域
front->next = t->next; //更新队首指针
if (t == front) //如果队首与队尾相同,则将队尾指针指向队首
rear = front;
free(t); //释放
return e; //返回队首数据域
}

int main()
{
Node rear = (Node)malloc(sizeof(Node));
Node *front = rear;
push(rear, 1);
push(rear, 2);
push(rear, 3);
int k = pop(rear, front);
printf("%d\n", k);
k = pop(rear, front);
printf("%d\n", k);
k = pop(rear, front);
printf("%d\n", k);
return 0;
}


MAXSIZE队列长度
循环队列满的条件:(rear + 1) % MAXSIZE == front
循环队列空的条件:rear == front
循环队列出队:front = (front + 1) % MAXSIZE
循环队列入队:rear = (rear + 1) % MAXSIZE
循环队列的长度:(MAXSIZE + rear – front)% MAXSIZE
感觉好麻烦(⊙o⊙)…

首先,你这个代码里面真的是错误百出,第一个正确的实例都有错误,Node node = (Node)malloc(sizeof(Node)); //分配空间 这个malloc返回的是一个指针,怎么能直接转成一个结构体呢,应该是Node* node = (Node*)malloc(sizeof(Node)); //分配空间 这样的。正确的实例我等下放上来。

第二个正确的代码应该是这样的。


#include<stdio.h>
#include<stdlib.h>

typedef struct Node
{
       int data;
       struct Node *next;
}Node;

typedef struct Q
{
       Node *front;
       Node *rear;
}Q;

void push(Q*q, int e)
{
       Node *node = (Node*)malloc(sizeof(Node));       //分配空间
       node->data = e;     //数据域
       node->next = NULL;  //指针域
       q->rear->next = node;   //添加到末尾
       q->rear = node;     //更新尾指针
}

int pop(Q* q)
{
       if (q->front == q->rear)
           return -1;
       Node *t = q->front->next;       //获取队首元素
       int e = t->data;        //获取队首数据域
       q->front->next = t->next;       //更新队首指针
       if (t == q->front)  //如果队首与队尾相同,则将队尾指针指向队首
           q->rear = q->front;
       free(t);        //释放
       return e;       //返回队首数据域
}


int main()
{
       Q queue;
       queue.rear = (Node*)malloc(sizeof(Node));
       queue.front = queue.rear;
       push(&queue, 1);
       push(&queue, 2);
       push(&queue, 3);
       int k = pop(&queue);
       printf("%d\n", k);
       k = pop(&queue);
       printf("%d\n", k);
       k = pop(&queue);
       printf("%d\n", k);
       return 0;
}

因为你传到push函数内的 Node* rear 指针实际是 main 函数内的 rear指针的一个拷贝。你在push里改变rear指针的值是不会影响到main函数里的rear指针的。因此你要传指针的指针。具体代码见上面

发错了... 第二个正确的代码是这个


#include <stdio.h>
#include <string.h>

typedef struct Node
{
        int data;
        struct Node *next;
}Node;
void push(Node** rear, int e)
{
        Node* node = (Node*)malloc(sizeof(Node)); //分配空间
        node->data = e; //数据域
        node->next = NULL; //指针域
        (*rear)->next = node; //添加到末尾
        *rear = node; //更新尾指针
}
int pop(Node* rear, Node* front)
{
        if (front == rear)
                return -1;
        Node *t = front->next; //获取队首元素
        int e = t->data; //获取队首数据域
        front->next = t->next; //更新队首指针
        if (t == front) //如果队首与队尾相同,则将队尾指针指向队首
                rear = front;
        free(t); //释放
        return e; //返回队首数据域
}
int main()
{
        Node* rear = (Node*)malloc(sizeof(Node));
        Node *front = rear;
        push(&rear, 1);
        push(&rear, 2);
        push(&rear, 3);
        int k = pop(rear,front);
        printf("%d\n", k);
        k = pop(rear, front);
        printf("%d\n", k);
        k = pop(rear, front);
        printf("%d\n", k);
        return 0;
}

#include
#include

typedef struct Node
{
int data;
struct Node *next;
}Node;

typedef struct Q
{
Node *front;
Node *rear;
}Q;

void push(Q*q, int e)
{
Node node = (Node)malloc(sizeof(Node)); //分配空间
node->data = e; //数据域
node->next = NULL; //指针域
q->rear->next = node; //添加到末尾
q->rear = node; //更新尾指针
}

int pop(Q* q)
{
if (q->front == q->rear)
return -1;
Node *t = q->front->next; //获取队首元素
int e = t->data; //获取队首数据域
q->front->next = t->next; //更新队首指针
if (t == q->front) //如果队首与队尾相同,则将队尾指针指向队首
q->rear = q->front;
free(t); //释放
return e; //返回队首数据域
}

int main()
{
Q queue;
queue.rear = (Node*)malloc(sizeof(Node));
queue.front = queue.rear;
push(&queue, 1);
push(&queue, 2);
push(&queue, 3);
int k = pop(&queue);
printf("%d\n", k);
k = pop(&queue);
printf("%d\n", k);
k = pop(&queue);
printf("%d\n", k);
return 0;
}

我的代码相对简单些 只 改了两个地方void push(Node* &rear, int e) int pop(Node* &rear, Node* front) 就可以了,望采纳! 不懂得可以继续问

再说最后一下,还记得讲指针经典的交换两个数,其实并不是 每一次rear改变会是的front同时改变 是队头队尾指针压根都没有变 而第一个程序,新建一个Q,Q中有NODE指针,也就是用的指针修改当然就可以了