您的位置:首页 > 编程语言 > C语言/C++

【回忆c语言】从指针的定义初始化到链表的插入删除排序实现code

2010-05-26 11:11 615 查看
// vs08下写的
// pointC.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"

float average(float *p);
int cpystr(char *pss,char *pds);
void cpystr2(char *pss,char *pds);

int _tmain(int argc, _TCHAR* argv[])
{
int aa=5;
int *p=&aa;
int *p1=p;


//指针数组才存在加减情况
float b[3]={23,233,342};
float *p2=b;
float *p3=&b[0];

printf("%d/n",(b+1));
printf("%d/n",(p3+1)); //b+1与p3+1一致的。不过需要区分的是:p3是变量,b和&b[0]是常量。
printf("%d/n",&*(p3));
printf("%d/n",&b[0]);

//指针比较:高位和低位
if((p3+1)>p2)
{
printf("%s/n","qiaoyong!");
}

//指代对应变量值
float c=*(p2+1)**p3;
printf("%f/n",c);

//与比较
if(p2!=0)
{
printf("%s/n","p2不是空指针!");
}

//为指针赋予值
#define null 0
int *p4=null;
if(0==p4)
{
printf("p4是空指针!/n");
}

//循环
for(int i=0;i<3;i++)
{
*p2=(float)i*i;
p2++;
}

p2=b; //重新设定指针值

for(int i=0;i<3;i++)
{
printf("%f/n",*p2);
p2++;
}

//上面两部可以更简洁的写为:


printf("简单的写法:/n");

for(int i=0;i<3;)
{
*p3=(float)i*i;
printf("%d:%f/n",i++,*p3++);
}

//总结:
//当前这里无论是int还是float,指针加一都是移动了个内存单元(字节),位。

//指针作为函数形参
//for(int i=0;i<3;i++)
//{
// scanf_s("%f",b+i);
//}

////调用average
//printf("平均值为:%f/n",average(b));


// 多维数组

printf("/n多维数组情况:/n");

#define PF "%d,%d,%d,%d,%d,/n"
static int a[3][4]={11,12,13,14,21,22,23,24,31,32,33,34};
printf(PF,a,*a,a[0],&a[0],&a[0][0]);
printf(PF,a+1,*(a+1),a[1],&a[1],&a[1][0]);
printf(PF,a+2,*(a+2),a[2],&a[2],&a[2][0]);
printf("仍然是地址,对应第二行第二列:%d,%d/n",a[1]+1,*(a+1)+1);
printf("%d,%d/n",*(a[1]+1),*(*(a+1)+1));

printf("以下为测试阶段:");
printf("%d,%d/n",*(a[1]+1),*(*(a+2)+3)); //也就是说,表示多维数组中的某个数,即可以用a[2][3],也可以用*(a+2)+3。

//不过上面用的是本身的指针,下面给出二维数组指针变量表示方法:
int(*p5)[4];
p5=a; // 要想再这里使用等号赋值,就必须使用上面的p5形式的二维数组指针变量,括号不能少,否则就变成了指针数组。
printf("如果使用二维数组指针变量:");
printf("%d,%d/n",*(p5[1]+1),*(*(p5+2)+3)); //也就是说,表示多维数组中的某个数,即可以用a[2][3],也可以用*(a+2)+3。






//**********************************************字符串使用***********
//字符串也是很特殊的变量,在c语言中。
char *p6; //char cc='q';
//p6=&(cc);
p6="hollo world!";
//printf("%c",p6);
printf("%s/n",p6);

//输出n个字符后的全部字符串
int nn=3;
p6+=nn;
printf("%s/n",p6); //nb,指针就是这么简单,要是在c#中你就要使用截肢函数了,制定初始,开始等等。这里,如何简洁。

char ss[20], *p7;
p7=ss;
//scanf("%s",p7);

//int i;

//for(i=0;p7[i]!='/0';i++)
//{
// if('k'==p7[i])
// {
// printf("k is here! /n");
// break;
// }
//}
//if('/0'==p7[i])
//{
// printf(" no k is this string!/n");
//}

//
static int a2[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
char *PF2; //按照我的理解,这里的char *就相当于string; 后面的使用也是类似的。
PF2="%d,%d,%d,%d,%d/n";
printf(PF2,a2,*a2,a2[0],&a2[0],&a2[0][0]); //指针指向字符串时,如需引用,无需加取值符号*。除了数组和字符串,常规c语言类型还是需要*的。
printf(PF2,a2+1,*(a2+1),a2[1],&a2[1],&a2[1][0]);
printf(PF2,a2+2,*(a2+2),a2[2],&a2[2],&a2[2][0]);
printf("%d,%d/n",a2[1]+1,*(a2+1)+1);
printf("%d,%d/n",*(a2[1]+1),*(*(a2+1)+1));

//copy string

char *first="hello,qiaoyong!",*second, fill[20];
second=fill;
printf("%s/n",first);



//second=first; //这里的效果是second也指向了first,但对fill没有什么改变
//printf("%s is copyed to %s!/n",first,second);
//printf("fill数组:%c/n",fill[1]);

//这样就改变了fill,不信你看:
second=fill; //second重新指向数组
while(*second++=*first++);
printf("%s is copyed to %s!/n",first-16,second-16);
printf("fill数组:%c/n",fill[1]);

//为了不修改实参的值,采用函数:
//首先初始化
second=fill; //second重新指向数组
first-=16;
//调用函数,我再次佩服一下指针
cpystr2(first,second);
printf("%s is copyed to %s!/n",first,second);
printf("fill数组:%c/n",fill[1]);


//结构使用
struct stu
{
char *name;
int age;
}qiao[]=
{
{"qiaoyong",10},
{"qiaozhi",6},
{"Zhang",2}
};

struct stu *pq;

for(pq=qiao;pq<qiao+3;pq++)
{
printf("name:%s, age:%d /n",pq->name,pq->age);
}

//下面进行内存分配
#define STU struct stu
STU *pq2;

pq2=(STU *)calloc(1,sizeof(STU));

pq2->name="fenpei";
pq2->age=1;

printf("动态分配内存calloc的应用:name:%s, age:%d /n",pq2->name,pq2->age);
free(pq2);


//下面进行链表操作
//1 构建一个链表
#define STP struct stu2
#define SIZE sizeof(STP)
STP
{
char *name;
int age;
STP *next;
};

STP *pf,*pb,*head;
//pb=(STP *)malloc(SIZE);
char temp[3][10]; //经过多次试验,证明struct中的指针赋值
for(int j=0;j<3;j++)
{
pb=(STP *)malloc(SIZE);
//scanf("%s",pb->name);//gets(pb->name);

//temp=" ";
scanf("%s",temp[j]);//gets(pb->name);
//为什么我直接赋的值就就可以输出,但是从console输入的值就不行能?
//也就是说,指针是无法直接从scanf中获取值的,但是我这里转化了,为什么也不行。
pb->name=temp[j];
scanf("%d",&pb->age);
if(0==j)
{
pf=head=pb;
}else
{
pf->next=pb;
}
pb->next=NULL;
pf=pb;
}

//输出刚才的链表
//free(pb);

STP * pstp;
pstp=head;
do
{
printf("输出刚才输入的:[%s,%d]/n",pstp->name,pstp->age);
pstp=pstp->next;
}while(pstp!=null);

//pstp=head;
/*pb=head;
do
{
printf("输出刚才输入的:[%s,%d]/n",pb->name,pb->age);
pb=pb->next;
}while(pb!=null);*/

//查找节点
int t=23;
STP *sp;
sp=head;
while(sp->age!=t && sp->next!=NULL)
{
sp=sp->next;
}
if(sp->age==t)
{
printf("找到了节点:name:%s,age:%d/n",sp->name,sp->age);
}
else
{
printf("没有找到节点/n");
}

//删除节点,仍以age值为为例。
//分为两种情况:第一个:删除的结点为首节点,第二:不是首节点
//经典的实现啊,呵呵
sp=head;
STP *pre;
pre=head;
do //把所有的满足条件的结点全部删除
{
if(t==sp->age && sp==head)
{
head=head->next;
}else if(t==sp->age && sp!=head )
{
pre->next=sp->next; //这一步就把当前的sp给干掉了
}
pre=sp;
sp=sp->next;
}while(sp!=NULL);

//输出链表**********
STP * pstp2;
pstp2=head;
printf("********************/n");
do
{
printf("删除age23节点后::[%s,%d]/n",pstp2->name,pstp2->age);
pstp2=pstp2->next;
}while(pstp2!=null);
printf("********************/n");
//输出链表**********END

//插入节点
STP *pi;
pi=(STP*)malloc(SIZE);
pi->name="insert2";
pi->age=20;
//pi->next=NULL;

//插入位置可能:head为空2 插入第一个位置3 插入中间位置4 插入最后一个节点
if(NULL==head)
{
head=pi;
pi->next=NULL;
}else
{
pb=head;
pf=head;
// find the insert position
while((pi->age>pb->age) && (pb->next!=NULL))
{
pf=pb;
pb=pb->next;
}
// if the position is in the middle
if(pi->age<=pb->age)
{
// if in the first pos
if(head==pb)
{
head=pi;
}else
{
pf->next=pi;
}
pi->next=pb;
}else //in the end position
{
pb->next=pi;
pi->next=NULL;
}
}



//输出链表**********
STP * pstp3;
pstp3=head;
printf("********************/n");
do
{
printf("插入后:[%s,%d]/n",pstp3->name,pstp3->age);
pstp3=pstp3->next;
}while(pstp3!=null);
printf("********************/n");
//输出链表**********END



//链表选择排序
STP *max,*tt,*out=NULL;

//为配合下面的最大值返回节点,在head前加一空节点,使其链表指向原有head
STP *blank;
blank=(STP*)malloc(SIZE);
blank->next=head;
head=blank;

while(head->next!=null)
{
//find the node before the max value node
pf=head;
pb=head->next;
int maxv=pb->age;
while(pb!=null)
{
if(pb->age>=maxv)
{
maxv=pb->age;
max=pf;
}
pf=pb;
pb=pb->next;
}

//以上的循环结束后,max指向了最大值节点的前一节点

tt=max->next;
max->next=tt->next; //delete the max node

tt->next=out;
out=tt;
}

head=out;

//输出链表**********
STP * pstp4;
pstp4=head;
printf("********************/n");
do
{
printf("排序:[%s,%d]/n",pstp4->name,pstp4->age);
pstp4=pstp4->next;
}while(pstp4!=null);
printf("********************/n");
//输出链表**********END







free(pi);
return 0;
}

float average(float *p)
{
float s=0;
for(int i=0;i<3;i++)
{
s+=*p++;
}
s=s/3;
return s;
}

int cpystr(char *pss,char *pds)
{
while((*pds=*pss)!='/0')
{
/*printf("first:%s/n",pss);
printf("second:%s/n",pds);
printf("first's char: %c/n",*pss);
printf("second's char:%c/n",*pds);*/
//可验证,如果char *p="string",这种类型的字符串指针,p输出为字符串"string",
// p+1输出就为"tring",但是*p输出就为第一个字符's',而p++后,则*p就为't';
pds++;
pss++;
}
return 0;
}

//cpystr的改进版,进一步简化
void cpystr2(char *pss,char *pds)
{
while(*pds++=*pss++);
}
//why,because 进一步分析还可发现`/0'的ASCⅡ码为,
//对于while语句只看表达式的值为非就循环,
//为则结束循环,因此也可省去“!=`/0'”这一判断部分
//靠,真是太nb了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐