首页 > 代码库 > 20140428 宏定义 单链表翻转 野指针

20140428 宏定义 单链表翻转 野指针

1、宏定义swap,加括号有什么意义

#define swap(x,y) x = (x)+(y);y=(x)-(y);x=(x)-(y)

加括号是为了处理表达式参数(即宏的参数可能是个算法表达式)时不出错,因为宏替换就是文本替换,所以如果有以下情况:
#define COM(A,B) (A)*(B)
那么COM(6+5,3),它会换成这样: (6+5)*(3)
但是如是去掉了定义中括号,即写成这样:
#define COM(A,B) A*B
那么COM(6+5,3),它就会换成这样:6+5*3
这样显然就和宏的意图不符合了。

2、单链表插入、删除、反转操作

#include<stdio.h>
#include<iostream>
#include<malloc.h>
#define swap(x,y) x=(x)+(y); y=(x)-(y); x=(x)-(y)
typedef struct student
{
    int data;
    struct student *next; 
}node;

node *create( )   //尾插法建立带头结点head的单链表
{
    node * head,*rear,*s;
    int x=0;
    head=(node *)malloc(sizeof(node *));
    head->data=http://www.mamicode.com/0;
    printf("please input data: ");
    scanf("%d",&x);
    rear=head;
    while(x!=0)
    {
        s=(node *)malloc(sizeof(node));
        s->data=http://www.mamicode.com/x;
        rear->next=s;
        rear=s;
        head->data++;
        printf("please input data: ");
        scanf("%d",&x);
    }
    rear->next=NULL;   //这句话一定加上,不然后果很严重
    return head;
}
int length(node *head)
{
    int n=0;
    node *rear=head->next;
    while(rear!=NULL)
    {n++;    rear=rear->next;}
    printf("the length is %d\n",n);
    return n;
}
void display(node *head)
{
    node *rear=head->next;
    while(rear!=NULL)
    {
        printf("%d ",rear->data);
        rear=rear->next;
    }
    printf("\n");
}
 int del_node1(node *head,int num)  //删除第一个data为num的节点
{
    node *p=head->next,*q=head;
    while(num!=p->data&&p!=NULL)
    {
        q=p;
        p=p->next;
    }
    if(p!=NULL)
    {
        q->next=p->next;
        free(p);
    }
    else 
        printf("\n could not find %d\n",num);
    return num;
}

 void insert_node(node *head,int num)   //在第一个大于等于num的节点之前插入, 带头结点的单链表,中间,末尾,开头插入都一样
 {
    node *p=head->next,*q=head;
     node *s=(node *)malloc(sizeof(node));
     s->data=http://www.mamicode.com/num;
     while(num>p->data&&p!=NULL)
     {
         q=p;
         p=p->next;
         if(p==NULL)
             break;
     }
     q->next=s;
     s->next=p;
 }

void sort(node *head) //升序,冒泡法
{
    int n=length(head);
    node *p,*q;
    for(int i=0;i<n;i++)
    {
        p=head->next;
        q=p->next;
        for(int j=1;j<(n-i);j++)//对于循环次数,以需要交换的次数来确定。
        {
            if(p->data>q->data)
            {swap(p->data,q->data);}
            p=p->next;
            q=p->next;
        }
    }
}

void reverse(node *head)
{
    if(head->next==NULL||head->next->next==NULL)
        return;
    node *p1=head->next,*p2=p1->next,*p3;
    while(p2!=NULL)
    {
        p3=p2->next;
        p2->next=p1;
        p1=p2;
        p2=p3;
    }
    head->next->next=NULL;
    head->next=p1;
}
void main()
{
    node *head=create();
    int delnode;
    length(head);
    display(head);
    //    del_node1(head,1);
    //insert_node(head,3);
    //sort(head);
    //reverse(head);
    display(head);
}

3、free,野指针

1、free只是释放了malloc所申请的内存,并不改变指针的值;
2、由于指针所指向的内存已经被释放,所以其它代码有机会改写其中的内容,相当于该指针从此指向了自己无法控制的地方,也称为野指针;
3、为了避免失误,最好在free之后,将指针指向NULL。

 

4、void *指针的作用

http://blog.163.com/njut_wangjian/blog/static/1657964252012419104537925/