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=0;
printf("please input data: ");
scanf("%d",&x);
rear=head;
while(x!=0)
{
s=(node *)malloc(sizeof(node));
s->data=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=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/

20140428 宏定义 单链表翻转 野指针,码迷,mamicode.com

时间: 2024-12-16 15:09:16

20140428 宏定义 单链表翻转 野指针的相关文章

将单链表翻转的两种方法

将一个单链表翻转的描述很简单,例如: 输入: NODE1->NODE2->NODE3->NODE4->NODE5->NULL 输出: NODE5->NODE4->NODE3->NODE2->NODE1->NULL 那么,定义单链表如下: (为简单起见,将data字段定义为int, 当然实际应用中data很可能是一个复杂的结构体) typedef struct list_s { int data; struct list_s *next; } li

Java实现单链表翻转

单链表翻转比如有如下链表: 需要按照C B A 输出,我们可以有好几种方法: package org.andy.test; import java.util.ArrayList; import java.util.List; /** * @author andy * @version:2015-2-4 上午9:41:12 * * */ public class LinkedReverse { /** * @param args */ public static void main(String[

C++ -&gt; 在使用动态链表和异质链表产生野指针的步骤

使用异质链表产生野指针的情况,下面是修改书本的例子: -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

单链表的头指针、头结点与首元结点

继续我们昨天所说的单链表.单链表也是一种线性表,所以总得有个头有个尾.链表中第一个结点的存储位置叫做头指针,那么整个链表的存取就必须是从头指针开始进行了.之后的每一个结点,其实就是上一个的后继指针指向的位置.雅加达娱乐城 这里有个地方要注意,就是对头指针概念的理解,这个很重要.“链表中第一个结点的存储位置叫做头指针”,如果链表有头结点,那么头指针就是指向头结点数据域的指针.画一个图吧. 这个图看起来很清晰了.比如说头结点,我们就可以这么描述了: 头结点是为了操作的统一与方便而设立的,放在第一个元

单链表翻转

方法一:通过三个指针来分别指向链表的当前节点.上一节点.下一节点 分别为P1,P2,P3. 上代码: static class Node{ int val; Node next; } public static Node reverse(Node node){ if (node==null||node.next==null){ return null; } Node current,pnext,prev; current=node.next; pnext=current.next; curren

已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)

对此题目的完整示例可直接运行代码如下: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int data; struct LNode *next; }LNode; LNode* creat(int n){ LNode *Link; LNode *p1,*p2; int data; Link=(LNode*)malloc(sizeof(LNode)); p2=Link; for(int i=0;i<n;+

C,单链表翻转函数

struct ST_StackNode{int num; datatype data; struct ST_StackNode *pNext; //指针域};typedef struct ST_StackNode StackNode; StackNode reverse(StackNode phead){if (phead == NULL){ return NULL; }if (phead->pNext == NULL) { return phead; } StackNode* pre, *cu

单链表翻转的几种写法

/* * 带头节点 */ ListNode * reverse(ListNode *head) { if (head == NULL || head->next == NULL) return head; ListNode nhead(-1);//头节点 nhead.next = head; ListNode *prev = head; ListNode *next = head->next; while (next != NULL) { prev->next = next->ne

动态单链表的传统存储方式和10种常见操作-C语言实现

顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. 一般链表的存储方法 一组物理位置任意的存储单元来存放线性表的数据元素,当然物理位置可以连续,也可以不连续,或者离散的分配到内存中的任意位置上都是可以的.故链表的逻辑顺序和物理顺序不一定一样. 因为,链表的逻辑关系和物理关系没有必然联系,那么表示数据元素之间的逻辑映象就要使用指针,每一个存储数据元素