预习检查:
1.linux下的文件描述符
2.二进制文件与文本文件的区别
3.如何从标准输入得到一行但如果避免使用gets()
**********************************************
1.文件的分类:
从用户观点:
特殊文件(标准输入输出文件或标准设备文件)
普通文件(磁盘文件)
从操作系统的角度看,每一个与主机相连的输入输出设备看做是一个文件。
2.文件:存储在外部介质上数据的集合,是操作系统管理的单位。
系统调度的最小单位--线程
分配资源的最小单位--进程
管理数据的单位------文件
3.文件概念
C把文件看做是一个字符的序,计由一个一个字符组成的字符流。
二进制文件就是内存的镜像文件
文本文件特点:存储量大,转换为二进制速度慢,直观易记。ASCII形式
二进制文件特点:存储量小,无需转换。但因一个字节不对应一个字符,故不能
直接输出其字符形式。二进制形式
4.文件系统
缓冲文件系统(高级文件系统):系统自动为正在使用的文件开辟内存缓冲区
非缓冲文件系统(低级文件系统):由用户在程序中为每个文件设定缓冲区。
------------------------------------------------------------------------------
句的格式以换行表示,ASCII值为10,十六进制表示为0A
结束标志EOF看不到
**********************************************************************
字符串输入 fgets
函数首部:
char *fgets(char *str,int length,FILE *fp);
功能:从fp所指向的文件中,至多读length-1个字符,送入字符数组str中,
如果在读入length-1个字符结束前遇换行符或EOF,读入即结束,字符串读入
后在最后加一个‘\0’字符。
返值:正常,返str指针;出错,返空指针NULL。
字符串输出 fputs
函数首部:
int *fputs(char *str,FILE *fp);
功能:把str指向的字符串写入fp指向的文件。
返值:正常,返0;出错返EOF。
######################################################################
字段输入fread /输出fwrite
函数首部:
int fread(void *buffer,int num_bytes, int count,FILE *fp);
int fwrite(void *buffer,int num_bytes, int count,FILE *fp);
功能:读/写数据块。
返值:成功,返回读/写的字段数;出错或文件结束,返回0。
说明:
buffer: 指向要输入/输出数据存储区的首地址的指针
num_bytes: 每个要读/写的字段的字节数
count: 要读/写的字段的个数
fp: 要读/写的文件指针
fread与fwrite 一般用于二进制文件的输入/输出。
***********************************************************************
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp = fopen("xxx","r");
if(fp == NULL)
{
printf("open error!!");
exit(0);
}
FILE *fw = fopen("zzz","w");
if(fw == NULL)
{
printf("open error!!");
exit(0);
}
char str[10];
while((fgets(str,10,fp)!=NULL))
{
printf("%s",str);
fputs(str,fw);
}
close(fp);
close(fw);
return 0;
}
运行结果:
123456789012345
123456789
cc
d
***********************************************************************
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp = fopen("xxx","r");
if(fp == NULL)
{
printf("open error!!");
exit(0);
}
char str[10];
while(fgets(str,10,fp)!=NULL)
{
printf("%s",str);
}
close(fp);
return 0;
}
运行结果:
123456789012345
123456789
cc
d
***********************************************************************
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[10]={65,66,67,68,69,70,71,72,73,74};
FILE *fp = fopen("xxx","w+");//注意要用w+
if(NULL == fp) //防止少写一个=导致报错
{
printf("open xxx error\n");
exit(0);
}
fwrite(a,sizeof(int),10,fp);
rewind(fp);
int b[10]={0};
fread(b,4,10,fp);
int i;
for(i=0;i<10;i++)
{
printf("%d ",b[i]);
}
fclose(fp);
return 0;
}
运行结果:
65 66 67 68 69 70 71 72 73 74
*************************************************************
rewind函数
函数首部: void rewind(FILE *fp);
功能:使fp所指文件的位置指针重置到文件开头。
返值:无
*************************************************************
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char a[]="china is great";
FILE *fp = fopen("xxx","w+");
if(NULL == fp) //防止少写一个=导致报错
{
printf("open xxx error\n");
exit(0);
}
fwrite(a,sizeof(char),strlen(a),fp);
rewind(fp); //使fp所指文件的位置指针重置到文件开头
char b[20];
fread(b,1,strlen(a),fp);
puts(b);
fclose(fp);
return 0;
}
运行结果:
china is great
****************************************************************
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{
char name[30];
int num;
char sex;
float score;
};
int main()
{
struct Stu stu[3]=
{
"bob",2001,'f',56,
"smith",2002,'m',45.0,
"calos",2003,'f',78
};
FILE *fp = fopen("studata","w+");
if(NULL == fp) //防止少写一个=导致报错
{
printf("open studate !");
exit(0);
}
fwrite(stu,sizeof(struct Stu),3,fp);
struct Stu x[3];
rewind(fp); //使fp所指文件的位置指针重置到文件开头
fread(x,sizeof(struct Stu),3,fp);
int i;
for(i=0;i<3;i++)
{
printf("%s %d %c %f\n",
x[i].name,x[i].num,x[i].sex,x[i].score);
}
fclose(fp);
return 0;
}
运行结果:
bob 2001 f 56.000000
smith 2002 m 45.000000
calos 2003 f 78.000000
*********************************************************************
stdin和stdout
例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
* fgets(char*,len,FILE*);
* fgets(char*,FILE*);
*
* 系统默认打开两个文件,分别对应的指针是:stdin(键盘),stdout(显示器)
*/
int main()
{
char *p = "china";
FILE *fp = fopen("mm","w");
fputs(p,stdout);
fputs(p,fp);
return 0;
}
运行结果:
china
同时将china写入文件mm中了
*************************************************************************
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
* fgets(char*,len,FILE*);
* fgets(char*,FILE*);
*
* 系统默认打开两个文件,分别对应的指针是:stdin(键盘),stdout(显示器)
*/
int main()
{
setvbuf(stdout,NULL,_IONBF,0);
char q[10];
FILE *fp = fopen("mm","r+");
fgets(q,10,fp);
printf("%s",q);
fclose(fp);
fgets(q,10,stdin);//只读入9+\0
//gets(q); //若写入20个数据,可能将q后的内存覆盖
printf("%s",q);
return 0;
}
运行结果:
who am i //打印结果
who am i //输入
who am i //输出
*********************************************************************
fseek函数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
FILE *fp = fopen("mm","r+");
if(NULL == fp)
{
printf("open error !");
exit(0);
}
int size;
fseek(fp,-1,SEEK_END);
size = ftell(fp);
printf("%d",size);
return 0;
}
**********************************************************************
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int num;
char name[20];
};
typedef struct Node STU;
int main()
{
FILE *fp;
fp = fopen("data.txt","w+");
if(fp == NULL)
{
printf("open error\n");
exit(0);
}
STU stu[5]={{10,"aaa"},{11,"bbb"},{12,"ccc"},{13,"ddd"},{14,"eee"}};
STU student2;
fwrite(stu,sizeof(STU),5,fp);
rewind(fp); //文件指针指向文件首部,读取第一个学生的信息
fread(&student2,sizeof(STU),1,fp);
printf("%d %s\n",student2.num,student2.name);
fseek(fp,2*sizeof(STU),SEEK_SET); //定位到第三个学生的位置,读取出信息
fread(&student2,sizeof(STU),1,fp);
printf("%d %s\n",student2.num,student2.name);
fclose(fp);
return 0;
}
运行结果:
10 aaa
12 ccc
****************************************************
#include<stdio.h>
int main(int argc,char *argv[])
{
printf("%d\n",argc);
return 0;
}
运行结果:
1
***********************************
[root@localhost 6.1]# ./a.out
1
[root@localhost 6.1]# ./a.out a
2
[root@localhost 6.1]# ./a.out a b
3
[root@localhost 6.1]# ./a.out a b c
4
[root@localhost 6.1]# ./a.out a b c d
5
***********************************
#include<stdio.h>
int main(int argc,char *argv[])
{
printf("%d\n",argc);
int i;
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
return 0;
}
运行结果:
[root@localhost 6.1]# ./a.out abc def ghi
4
./a.out
abc
def
ghi
分析: argc=4
argv[0]->./a.out
argv[1]->abc
argv[2]->def
argv[3]->ghi
*********************************************
atoi(将字符串转换成整型数)
相关函数 atof,atol,atrtod,strtol,strtoul
表头文件 #include<stdlib.h>
定义函数 int atoi(const char *nptr);
函数说明 atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才
开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。
返回值 返回转换后的整型数。
附加说明 atoi()与使用strtol(nptr,(char**)NULL,10);结果相同。
范例 /* 将字符串a 与字符串b转换成数字后相加*/
#include<stdlib.h>
mian()
{
char a[]=”-100”;
char b[]=”456”;
int c;
c=atoi(a)+atoi(b);
printf(c=%d\n”,c);
}
执行 c=356
*****************************************
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
if(argc != 2)
{
printf("Please input like ./a.out argment\n");
exit(0);
}
int num,i;
num = atoi(argv[1]);//将字符串转化为对应的整型数
for(i=0;i<num;i++)
{
printf("xxx\n");
}
return 0;
}
运行结果:
[root@localhost 6.1]# ./a.out 2
xxx
xxx
[root@localhost 6.1]# ./a.out 3
xxx
xxx
xxx
**************************************
数组指针:(本质是指针,指向的是数组)
void func(int (*p)[4],int n)
其中,n为长度,即跳的次数
代码举例:
#include<stdio.h>
#include<stdlib.h>
void func(int (*p)[4],int n);
int main()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
func(a,3);
return 0;
}
void func(int (*p)[4],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<4;j++)
{
printf("%3d",p[i][j]);
}
printf("\n");
}
}
运行结果:
1 2 3 4
5 6 7 8
9 10 11 12
********************************************************
预习检查:
1.预编译是什么?
答:在进行第一遍扫描(词法分析和语法分析)之前所作的工作
2.如何得到只经过编译后的文件?
答:gcc -E 文件名.c -o 文件名.i
3.#include<stdio.h>
********************************************************
宏定义:不带参数的:
一般形式:#define 宏名 [宏体]
以#开头的都发生在预处理阶段
#include<stdio.h>
#define YES 1
#define OUT printf("xxxxx\n");
int main()
{
int a=YES;
if(a==YES)
{
OUT;
}
return 0;
}
*****************************************************************
#include<stdio.h>
#define NUM 5+4 //没加括号结果为21,加上括号结果为36
#define OUT printf("xxxxx\n");
int main()
{
int a=NUM*4;
printf("%d\n",a);
return 0;
}
运行结果:
21
****************************************************
带参宏定义:
#define S(a,b) a*b 注意:S和(a,b)之间不能有空格
……
area = S(3,2) //area=3*2
****************************************************
取消宏定义:
#undef A
*********************************************
条件编译:
#if条件 //当条件为假(0)的时候,注释下面语句
#else //与#if相反,#if注释是这里不注释
#endif
*********************************************
#define BZ
#ifdef BZ
……
#else
…… //注释掉
#endif
****************
没有#define BZ
#ifdef BZ
…… //注释掉
#else
……
#endif
******************************************
#define M 8086 //谁与此不同,则被注释掉
#if M==8086
……
#if M==51
…… //注释掉
#if M==2000
…… //注释掉
#endif
******************************************
#include<stdio.h>
#include<stdlib.h>
void why_me();
int main()
{
printf("The file is%s.\n",__FILE__);
printf("The file is%s.\n",__DATE__);
printf("The file is%s.\n",__TIME__);
printf("The file is%d.\n",__LINE__);
printf("The file is%s.\n",__func__);
why_me();
return 0;
}
void why_me()
{
printf("This function is%s\n",__func__);
printf("This function is%s\n",__FILE__);
printf("This function is%d\n",__LINE__);
}
运行结果:
The file is../src/hello.c.
The file isJun 1 2012.
The file is21:02:35.
The file is9.
The file ismain.
This function iswhy_me
This function is../src/hello.c
This function is18
***************************************************
文件包含:
被包含文件的内容:
@源文件(*.c)
@头文件(*.h):宏定义,数据结构定义,函数说明等
$例$
文件a.c:
#include"agou.h"
aaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbb
cccccccccccccc
ddddddddddd
eeeeeeee
fffff
ggg
h
文件agou.h
x
yyy
zzzzzzzzzzz
xxxxxxxxxxxxx
vvvvvvvvvvvvvvvvvv
qqqqqqqqqqqqqqqqqqqqqqqq
预处理一下a.c:
gcc -E a.c -o a.i
打开预处理后的文件a.i,内容如下:
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "a.c"
# 1 "agou.h" 1
x
yyy
zzzzzzzzzzz
xxxxxxxxxxxxx
vvvvvvvvvvvvvvvvvv
qqqqqqqqqqqqqqqqqqqqqqqq
# 2 "a.c" 2
aaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbb
cccccccccccccc
ddddddddddd
eeeeeeee
fffff
ggg
h
***************************************
避免头文件重复包含:
#ifndef _XXX_H_ //若未定义,则定义
#define _XXX_H_
文件内容
#endif
***************************************
位运算: 逻辑运算符
按位与运算 & 逻辑与 &&
按位或运算 | 逻辑或 ||
按位求反运算 ~ 非运算 !
按位异或运算 ^
左移运算 a<<4
右移运算 b>>3
********************************
输出二进制数据:
#include<stdio.h>
#include<stdlib.h>
void bindisp(int a)
{
int i=32;
while(i--)
{
if(a&(1<<i))
printf("1");
else
printf("0");
if(i%8==0)
printf(" ");
}
putchar(10);
}
int main()
{
setvbuf(stdout,NULL,_IONBF,0);
bindisp(3);
bindisp(11);
bindisp(3&11);
return 0;
}
运行结果:
00000000 00000000 00000000 00000011 //3
00000000 00000000 00000000 00001011 //11
00000000 00000000 00000000 00000011 //3&11
*******************************************
按位与:
格式:x&y
规则:对应位均为1时才为1,否则为0
如: 3&11 0011
&1011
——
0011 =3(十进制)
故 3&11=3
特点:和1与运算都为本身,和0与运算则为0
通常用法:将某些位清零。如与255(二进制为00000000 11111111)按位与,即把数据的低八位保留,
其余高位全清零
*******************************************
按位或:
格式: x|y
规则:对应位均为0时才为0,否则为1
如: 3|9 0011
|1001
------
1011 =11(十进制)
故 3|9=11
特点:和0或运算,不变;和1或,置1
通常用法:将某些位置1 。如:将0x50(二进制为0101 0000)与0x0f(0000 1111)或运算,
结果为0x5f(0101 1111)
*******************************************
按位取反:
格式: ~x
规则:1取反变为0,0取反变为1
如: ~3 ~0011=1100
*******************************************
异或:
格式:x^y
规则:相异者(即0,1)或,为1;相同者为0
如: 3^9 0011
^1001
-------
1010 =10(十进制)
故 3^9=10
特点:与全1异或,相当于取反;与全0异或,不变
如:将低4位取反,高4位保持不变,与0x0f异或
********************************************
左移:
格式:x<<n
规则:将x左移n位
特点:左移一位相当于乘2
********************************************
右移:
格式:x>>n
规则:将x右移n位
特点:左移一位相当于除2
********************************************
综合题:
1.将一int型数据8~11位(0位起),清零
int val = 0xffff; //1111 1111 1111 1111
val = val & (~(0xf<<8));//和1111 0000 1111 1111做与运算
bindisp(val); //结果为1111 0000 1111 1111
2.将一int型数据8~11位(0位起),置1
int val = 0x0000;
val = val | (0xf<<8);
bindisp(val);
3.将一int型数据8~11位(0位起),取出
法一: int val = 0xf5ff;
val &= (0xf<<8);
val >>= 8; //val = val>>8;
bindisp(val);
printf("%d",val);
结果为:00000000 00000000 00000000 00000101
5
法二: int val = 0xf5ff;
val >>= 8; //val = val>>8;
val &=0xf;
bindisp(val);
printf("%d",val);
结果为:00000000 00000000 00000000 00000101
5
*****************************************
位域(位段):
含义:位域是以位为单位定义长度的结构体类型中德成员
位段的构成:
例如:声明一个位段结构,并定义一个变量data
struct pack
{
unsigned a:1;
unsigned b:2;
unsigned c:3;
}data;
-----------------------------------------
#include<stdio.h>
#include<stdlib.h>
struct pack
{
unsigned int a:1;
unsigned int b:2;
unsigned int c:3;
};
int main()
{
struct pack a={1,3,7};
printf("%d\n",a.a);
printf("%d\n",a.b);
printf("%d\n",a.c);
return 0;
}
运行结果:
1
3
7
----------------------------------------
#include<stdio.h>
#include<stdlib.h>
int main()
{
struct pack
{
unsigned a:1;
unsigned b:2;
unsigned c:3;
}bit,*pbit;
bit.a=1;
bit.b=7;
bit.c=15;
printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
pbit=&bit;
pbit->a=0;
pbit->b&=3;
pbit->c|=1;
printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);
return 0;
}
运行结果:
1,3,7
0,3,7
********************************************
函数指针:
程序举例:
#include<stdio.h>
#include<stdlib.h>
int max(int a,int b)
{
return a>b?a:b;
}
int main(void)
{
int (*p)(int,int); //注意*p要加括号
int a = 5;
int b = 6;
p = &max; //p指向函数max
printf("%d\n",(*p)(a,b));
return 0;
}
运行结果:
6
--------------------------------------------
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *func(char *p1,char *p2)
{
int i=0;
i=strcmp(p1,p2);
if(i==0)
return p1;
else
return p2;
}
int main()
{
char* (*pf) (char*,char*);//函数指针
pf=&func;
printf("%s",(*pf)("aa","bb"));
return 0;
}
运行结果:
bb
********************************************
const--只读
如const int a;
a = 12; //报错,a为只读
一旦定义,其值不可改变,所以必须要赋初值
int main()
{
int a=12;
int b =34;
// int const *p = &a;
// *p = 12;
// p = &b;
// int * const q = &a;
// *q = 12;
// q = &b;
int const *const q =&a;
q = &b;
*q = 12;
return 0;
}
******************************************************
数组及动态申请
数组三要素:类型,长度,首地址
动态申请的空间在堆内
程序举例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *p;
p = malloc(sizeof(char)*10);//动态申请了10个字符空间
strcpy(p,"china\n");
printf("%s",p);
free(p); //用完要释放
return 0;
}
Malloc申请的空间处于受保护状态,若不及时释放,其他程序无法使用此段空间。
********************************
typedef给变量起别名
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#if 0
typedef int GS; //typerename
typedef int INT32;
typedef short INT16;
typedef char INT8;
#endif
#define INT32 int
#define INT16 short
#define INT8 char
int main()
{
INT32 a;
INT16 b;
INT8 c;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(b));
printf("%d\n",sizeof(c));
return 0;
}
--------------------------------------
typedef与宏定义的区别:
typedef int INT32;
#define INT32 int
1.首先,书写顺序不同
2.typedef后面必须有分号;
3.执行的时间段不同,宏定义在预处理的时候执行,而typedef和一般C语句一样
4.typedef相当于新定义了一个类型,若typedef char* INT8p;则执行INT8p p,q;相当于char *P,*q;
p和q都是char*型
而宏定义只是单纯的文本替换,如#define INT8p char*,则执行INT8p p,q; 时,只是把INT8p替换为char*,也就是char *P,q;
p为指针变量,q为字符变量
---------------------------------------
typedef举例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char INT8;
typedef char* INT8p;
int main()
{
INT8 a;
INT8p p,q; //等价于char *p,*q;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(p));
printf("%d\n",sizeof(q));
return 0;
}
运行结果:
1
4
4
-----------------------------------------
宏定义举例:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INT8 char
#define INT8p char*
int main()
{
INT8 a;
INT8p p,q; //等价于char *p,q;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(p));
printf("%d\n",sizeof(q));
return 0;
}
运行结果:
1
4
1
------------------------------------------
typedef定义技巧:
1.若想定义形如char a,*p;
只需在前面加上typedef,在将a改为别名INT8,将p改为INT8p
即写为:typedef char INT8,*INT8p;
2.定义数组
typedef int T[10];
引用时用:T m; //相当于int m[10]
3.结构体
typedef struct Stu
*******************************************
enum(属于构造类型)
用enum关键字说明枚举常量有三点好处:
1.用enum关键字说明的常量由编译程序自动生成,程序员不需要手工对常量一一赋值
2.用enum关键字说明常量使程序更清晰易读,因为在定义enum常量的同时也定义了一个枚举类型标示符
3.在调试程序时通常可以检查枚举常量,这一点非常有用,不用手工检查头文件中的常量值
enum与define相比,有以下好处:
1.
2.
3.
程序举例:
#include<stdio.h>
enum color {red,yellow,blue=7,white,black};
int main()
{
enum color pri;
for(pri=red;pri<=black;pri++)
{
switch(pri)
{
case red: printf("red->%d\n",red);
break;
case yellow: printf("yellow->%d\n",yellow);
break;
case blue: printf("blue->%d\n",blue);
break;
case white: printf("white->%d\n",white);
break;
case black: printf("red->%d\n",black);
break;
default:;
}
}
return 0;
}
运行结果:
red->0
yellow->1
blue->7
white->8
red->9
********************************************
static
static修饰的函数只适用于它所定义的文件中
---------------------
文件static.c如下
---------------------
#include<stdio.h>
void display();
void haha();
int main()
{
display();
haha(); //这里调用被拒绝
return 0;
}
----------------------
文件fun.c如下
----------------------
#include<stdio.h>
static void haha();
void display()
{
haha();
}
static void haha()
{
printf("haha\n");
}
-----------------------
由于在static.c的main函数中调用了display()和haha(),而函数haha()被static修饰,所以,当在main函数中调用haha时,系统会提示undefined reference to `haha',而main函数中调用的display()没有被static修饰,可以被调用,而且display()又调用了haha(),此时由于函数display()和函数haha()在同一文件内,故可以成功调用,最终main函数中调用的两个函数只有display()调用成功,直接调用haha()不成功
******************************************
各种变量在内存中的位置
#include<stdio.h>
int a; //data segment,bss aera, initialized with 0 by system
static int a; //data segment,bss aera, initialized with 0 by system
int c[10]={1,2,3,4}; //data segment,initialize rw aera
char *p = "china"; //p data initialize,rw
//"china"data initialize read-only
int main()
{
int i,j; //stack
static int m; //data segment,bss aera, initialized with 0 by system
static int n = 6; //data initialize rw
int x[5] = {1,2,3,4,5}; //x[] stack
//{1,2,3,4,5} data initialize read-only
char y[] = "i love xxx"; //y[] stack
//"i love xxx" data initialize read-only
char *q = "who i am"; //q stack
//"who i am" data initialize read-only
char *k = malloc(sizeof(int)*10);//k stack
//malloc heap
return 0;
}
*******************************************
******
*排序*
******
-------------------------------------------
1.选择排序法
基本思想:
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
代码举例:
#include<stdio.h>
void SelectSort(int *a,int N);
int main()
{
int a[5]={5,4,3,2,1};
int i;
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
printf("\n");
SelectSort(a,5);
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
return 0;
}
void SelectSort(int *a,int N)
{
int i,j,tmp;
for(i=0;i<N-1;i++) //控制比较趟数
{
for(j=i+1;j<N;j++)
{
if(a[i]>a[j])
{
tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}
}
}
运行结果:
54321
12345
--------------------------------------------
2.冒泡排序:
基本思想:
冒泡排序是经过n-1趟子排序完成的,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数
代码举例:
#include<stdio.h>
void PopSort(int *p,int N);
int main()
{
int a[5]={5,4,3,2,1};
int i;
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
printf("\n");
PopSort(a,5);
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
return 0;
}
void PopSort(int *p,int N)
{
int i,j,tmp;
for(i=0;i<N-1;i++)
{
for(j=0;j<N-i-1;j++)
{
if(p[j]>p[j+1])
{
tmp=p[j];
p[j]=p[j+1];
p[j+1]=tmp;
}
}
}
}
运行结果:
54321
12345
---------------------------------------------------
3.shell排序:
基本思想:
先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
代码举例:
#include<stdio.h>
void ShellSort(int *p,int N);
int main()
{
int a[5]={5,4,3,2,1};
int i;
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
printf("\n");
ShellSort(a,5);
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
return 0;
}
void ShellSort(int *p,int N)
{
int i,tmp,d=N;
while(d>1)
{
d=(d+1)/2;
for(i=0;i<N-d;i++)
{
if(p[i]>p[i+d])
{
tmp = p[i];
p[i] = p[i+d];
p[i+d]= tmp;
}
}
}
}
运行结果:
54321
12345
-------------------------------------------------
4.插入排序法
基本思想:
输入一个元素,检查数组列表中的每个元素,将其插入到一个已经排好序的数列中的适当位置,使数列依然有序,当最后一个元素放入合适位置时,该数组排序完毕。
例:输入一个数,插入一个各元素已经按照升序排列的数组中,插入后使数组中元素仍然是按照升序排列的。思想:把欲插入的数与数组中各数逐个比较, 当找到第一个比插入数大的元素i时,该元素之前即为插入位置。然后从数组最后一个元素开始到该元素为止,逐个后移一个单元。最后把插入数赋予元素a[i]即可。如果被插入数比所有的元素值都小则插入最前位置。
代码举例:
#include<stdio.h>
void InsertSort(int *p,int N);
int main()
{
int a[5]={5,4,3,2,1};
int i;
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
printf("\n");
InsertSort(a,5);
for(i=0;i<5;i++)
{
printf("%d",a[i]);
}
return 0;
}
void InsertSort(int *p,int N)
{
int i,tmp,j;
for(i=1;i<N;i++)
{
tmp = p[i];
for(j=i;j>0;j--)
{
if(tmp>p[j-1])
{
break;
}
else
{
p[j]=p[j-1];
}
}
p[j]=tmp;
}
}
运行结果:
54321
12345
---------------------------------------------
5.快速排序法
基本思想:
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
一趟快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1即J--),找到第一个小于key的值A[j],A[j]与A[i]交换; 4)从I开始向后搜索,即由前开始向后搜索(I=I+1即I++),找到第一个大于key的A[i],A[i]与A[j]交换; 5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
举例:
初始状态:
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 7 3 1 8 12 10 6 4
光标位置: low high
-----------------------------------------------------------------------------------
第一趟排序的具体过程:
1)将7拿出来(先放在tmp中),a[0]空;
2)将光标low指向的值4与7比较,4小,将4赋给a[0],a[7]空,则光标low移到a[1];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 8 12 10 6 7
光标位置: low high
3)3和7比,3小,low移到a[2];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 8 12 10 6 7
光标位置: low high
4)1和7比,1小,low移到a[3];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 8 12 10 6 7
光标位置: low high
5)p[low]即8和7比,8大,将8赋给p[high]即a[7],a[3]空;
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 12 10 6 8 7
光标位置: low high
6)p[low]空,将p[high]即a[7]的内容8与7比较,8大,故high移到a[6];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 12 10 6 8 7
光标位置: low high
7)将p[high]内容6于7比,6小,故把6赋给p[low]即a[3],a[6]空;
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 12 10 8 7
光标位置: low high
8)p[high]空,则比较p[low]和7,7大,则low移到a[4];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 12 10 8 7
光标位置: low high
9)p[low]和7比,p[low]大,则将p[low]赋给a[6],a[4]空;
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 10 12 8 7
光标位置: low high
10)p[low]空,则比较p[high]和7,7小,则将high移到a[5];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 10 12 8 7
光标位置: low high
11)将p[high]与7比较,7小,则将high移到a[4];
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 10 12 8 7
光标位置: low(high)
12)此时,low和high同时指向a[4],则把7赋给a[4].
13)最后,第一趟排序结束
位置: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] tmp
数值: 4 3 1 6 7 10 12 8 7
光标位置: low(high)
第一趟排序效果:7前面的都比7小,7后面的都比7大;
在一直这样继续下去,直至排序结束
------------------------------------------------------------------------------------
代码举例:
#include<stdio.h>
int FindPos(int *p,int low,int high)
{
int tmp = p[low];
while(low<high)
{
while(p[high]>tmp && (high>low))
high--;
p[low] = p[high];
while(p[low]<tmp && (high>low))
low++;
p[high] = p[low];
}
p[low] = tmp;
return high;
}
void QuickSort(int *p,int low,int high)
{
int pos;
if(low<high)
{
pos = FindPos(p,low,high);
QuickSort(p,low,pos-1);
QuickSort(p,low+1,high);
}
}
int main()
{
int a[5]={5,12,3,9,1};
int i;
for(i=0;i<5;i++)
{
printf("%d ",a[i]);
}
printf("\n");
QuickSort(a,0,4);
for(i=0;i<5;i++)
{
printf("%d ",a[i]);
}
return 0;
}
运行结果:
5 12 3 9 1
1 3 5 9 12
------------------------------------------------
链表:
链表中的最基本单元称为节点,包括两部分信息:存放数据元素信息的称为数据域,存放其后继地址的成为指针域。
结构:
(以4个节点为例)
-----------------------------------------------------------------------------------
节点:头指针p--> a(头节点) b(首节点) c d(尾节点)
data: 1(通常不放数据) 2 3 4
next: b首地址 c首地址 d首地址 NULL
-----------------------------------------------------------------------------------
插入新节点示意图:
-----------------
初始状态:
head-->【 | NULL】 cur-->【5|】
(1) cur-->next = head-->next;
head-->【 | 】 cur-->【5|NULL】
(2) head-->next = cur;
head-->【 | 】-->【5|NULL】
------------------------------------------------------
初始状态:
head-->【 | 】-->【5|NULL】 cur-->【4|】
(1) cur-->next = head-->next;
head-->【 | 】-->【5|】 cur-->【4|NULL】
(2) head-->next = cur;
head-->【 | 】-->【5|】 -->【4|NULL】
------------------------------------------------------
记住两句话:
(1)让新来的结点先有所指向
(2)箭头指向谁就是存放着人家的地址
------------------------------------------------------
静态链表举例:
#include <stdio.h>
struct node
{
int data;
struct node *next;
};
int main()
{
struct node a;
struct node b;
struct node c;
struct node d;
a.data = 1;
b.data = 2;
c.data = 3;
d.data = 4;
a.next = &b;
b.next = &c;
c.next = &d;
d.next = NULL; //不能忘记
struct node *p;
p = &a;
while(p!=NULL)
{
printf("%d ",p->data);
p = p->next;
}
return 0;
}
运行结果:
1 2 3 4
-----------------------------------------
上面程序改进:
#include <stdio.h>
typedef struct node //改进的地方
{
int data;
struct node *next;
}Node,*PNode; //改进的地方
int main()
{
Node a; //改进应用
Node b;
Node c;
Node d;
a.data = 1;
b.data = 2;
c.data = 3;
d.data = 4;
a.next = &b;
b.next = &c;
c.next = &d;
d.next = NULL;
PNode p; //改进应用
p = &a;
while(p!=NULL)
{
printf("%d ",p->data);
p = p->next;
}
return 0;
}
运行结果:
1 2 3 4
----------------------------------
动态链表
动态链表的创建,打印,求长度,插入,数据搜索
程序举例:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node,*PNode;
PNode CreatLink() //头插法
{
PNode head,cur; //定义头指针和要插入节点的指针
head = (PNode)malloc(sizeof(Node)); //malloc()返回void*型指针
head->next = NULL;//将头节点的指针域置为空
int tmp;
printf("Please input node:");
scanf("%d",&tmp);
while(tmp)
{
cur = (PNode)malloc(sizeof(Node));//申请空间
cur->data = tmp; //给数据域填充数值
cur->next = head->next;//将新插入节点的指针指向要插入位置的下一个节点
head->next = cur; //将要插入位置的上一节点的指针指向要插入节点
scanf("%d",&tmp);
}
return head;
}
void PrintLink(PNode head)
{
head = head->next; //将指针指向首节点
while(head != NULL)
{
printf("%d ",head->data);//打印节点数据
head = head->next; //将指针指向下一节点
}
printf("\n");
}
int LenLink(PNode head) //求链表的长度
{
int len = 0;
head = head->next; //将指针指向首节点
while(head != NULL) //若指针不为NULL,则len++,并将指针指向下一节点
{
len++;
head = head->next;
}
return len; //返回len
}
void InsertLink(PNode head)
{
int tmp;
PNode cur;
printf("Please input new node:\n");
scanf("%d",&tmp);
cur = (PNode)malloc(sizeof(Node));
cur->data = tmp;
cur->next = head->next;
head->next = cur;
}
PNode SearchLink(PNode head,int find)
{
head = head->next;
while(head != NULL)
{
if(head->data == find)
{
return head; //返回调用此函数的地方
}
head = head->next;
}
return NULL;
}
int main()
{
int len,find;
PNode head,pfind;
head = CreatLink();
PrintLink(head); //调用PrintLink()函数,打印链表数据
len = LenLink(head);
printf("The length of Link is %d\n",len);
InsertLink(head);//插入链表
PrintLink(head);
printf("Please input find:\n");
scanf("%d",&find);
SearchLink(head,find);
pfind = SearchLink(head,find);
if(pfind == NULL)
{
printf("your find is none\n");
}
else
{
printf("your find is %d\n",pfind->data);
}
return 0;
}
运行结果:
Please input node:1 2 3 4 5 0
5 4 3 2 1
The length of Link is 5
Please input new node:
99
99 5 4 3 2 1
Please input find:
2
your find is 2
-----------------------------------
结点的删除:
(1)使要删除的节点脱链
q->next = p->next;
(2)释放节点资源
free(p);
p = NULL;
节点删除函数:
void DeleteLink(PNode head,PNode pfind)
{
while(head->next != pfind && head != NULL)
head = head->next;
head->next = pfind->next;
free(pfind);
}
---------------------------------------------------
排序:(冒泡排序法)
(1)交换数据域:
图形示意:
函数如下:
void PopSortLink(PNode head,int len)
{
int i,j,tmp;
PNode p,q;
if(head->next == NULL || head->next->next == NULL)//除了头节点,至少还要有两个节点
return ;
for(i=0; i<len-1; i++)
{
p = head->next; //冒泡每次从头开始
q = p->next;
for(j=0; j<len-i-1; j++)
{
if(p->data>q->data)
{
tmp = p->data;
p->data = q->data;
q->data = tmp;
}
p = p->next;
q = q->next;
}
}
}
(2)交换指针域:
图形示意:
void PopSortLink(PNode head,int len)
{
int i,j;
PNode p,q,list,tmp;
if(head->next == NULL || head->next->next == NULL)
return ;
for(i=0; i<len-1; i++)
{
list = head; //保存头指针
p = list->next;//确定初始p,q指向
q = p->next;
for(j=0; j<len-1-i; j++)
{
if(p->data > q->data)
{
list->next = p->next; //交换p->next,q->next指向
p->next = q->next;
q->next = p;
tmp = p; //交换指针p和q
p = q;
q = tmp;
}
list = list->next;//重新确定p,q指向,即从头开始,以便下一趟比较
p = p->next;
q = q->next;
}
}
}
-------------------------------------------
将单链表倒置:
图形示意:
void ReverseLink(PNode head)
{
PNode p,q;
p = head->next;
head->next = NULL;
q = p;
while(q != NULL)
{
q = q->next;
p->next = head->next;
head->next = p;
p = q;
}
}
---------------------------------------------
链表总程序代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}Node,*PNode;
PNode CreatLink()
{
PNode head,cur; //定义头指针和要插入节点的指针
head = (PNode)malloc(sizeof(Node)); //malloc()返回void*型指针
head->next = NULL;//将头节点的指针域置为空
int tmp;
printf("Please input node:");
scanf("%d",&tmp);
while(tmp)
{
cur = (PNode)malloc(sizeof(Node));//申请空间
cur->data = tmp; //给数据域填充数值
cur->next = head->next;//将新插入节点的指针指向要插入位置的下一个节点
head->next = cur; //将要插入位置的上一节点的指针指向要插入节点
scanf("%d",&tmp);
}
return head;
}
void PrintLink(PNode head)
{
head = head->next; //将指针指向首节点
while(head != NULL)
{
printf("%d ",head->data);//打印节点数据
head = head->next; //将指针指向下一节点
}
printf("\n");
}
int LenLink(PNode head) //求链表的长度
{
int len = 0;
head = head->next; //将指针指向首节点
while(head != NULL) //若指针不为NULL,则len++,并将指针指向下一节点
{
len++;
head = head->next;
}
return len; //返回len
}
void InsertLink(PNode head)
{
int tmp;
PNode cur;
printf("Please input new node:\n");
scanf("%d",&tmp);
cur = (PNode)malloc(sizeof(Node));
cur->data = tmp;
cur->next = head->next;
head->next = cur;
}
PNode SearchLink(PNode head,int find)
{
head = head->next;
while(head != NULL)
{
if(head->data == find)
{
return head; //返回调用此函数的地方
}
head = head->next;
}
return NULL;
}
void DeleteLink(PNode head,PNode pfind)
{
while(head->next != pfind && head != NULL)
head = head->next;
head->next = pfind->next;
free(pfind);
}
#if 0
void PopSortLink(PNode head,int len)
{
int i,j,tmp;
PNode p,q;
if(head->next == NULL || head->next->next == NULL)
return ;
for(i=0; i<len-1; i++)
{
p = head->next; //冒泡每次从头开始
q = p->next;
for(j=0; j<len-i-1; j++)
{
if(p->data>q->data)
{
tmp = p->data;
p->data = q->data;
q->data = tmp;
}
p = p->next;
q = q->next;
}
}
}
#endif
void PopSortLink(PNode head,int len)
{
int i,j;
PNode p,q,list,tmp;
if(head->next == NULL || head->next->next == NULL)
return ;
for(i=0; i<len-1; i++)
{
list = head; //保存头指针
p = list->next;//确定初始p,q指向
q = p->next;
for(j=0; j<len-1-i; j++)
{
if(p->data > q->data)
{
list->next = p->next; //交换p->next,q->next指向
p->next = q->next;
q->next = p;
tmp = p; //交换指针p和q
p = q;
q = tmp;
}
list = list->next;//重新确定p,q指向,即从头开始,以便下一趟比较
p = p->next;
q = q->next;
}
}
}
void ReverseLink(PNode head)
{
PNode p,q;
p = head->next; //p指向第一个数据节点
head->next = NULL; //将原链表置为空表
q = p;
while(q != NULL)
{
q = q->next;
p->next = head->next;
head->next = p;
p = q;
}
}
void DestroyLink(PNode head)
{
PNode p = head;
while(p != NULL)
{
head = head->next;
free(p);
p = head;
}
}
int main()
{
int len,find;
PNode head,pfind;
head = CreatLink();
PrintLink(head); //调用PrintLink()函数,打印链表数据
len = LenLink(head);
printf("The length of Link is %d\n",len);
InsertLink(head);//插入链表
PrintLink(head);
printf("Please input find:\n");
scanf("%d",&find);
SearchLink(head,find);
pfind = SearchLink(head,find);
if(pfind == NULL)
{
printf("your find is none\n");
}
else
{
printf("your find is %d\n",pfind->data);
DeleteLink(head,pfind);
printf("after delete:\n");
PrintLink(head);
}
len = LenLink(head);
printf("After sort\n");
PopSortLink(head,len);
PrintLink(head);
ReverseLink(head);
printf("After reverse\n");
PrintLink(head);
DestroyLink(head);
printf("Link has been destroyed!\n");
return 0;
}
运行结果:
Please input node:1 2 3 4 5 0
5 4 3 2 1
The length of Link is 5
Please input new node:
33
33 5 4 3 2 1
Please input find:
4
your find is 4
after delete:
33 5 3 2 1
After sort
1 2 3 5 33
After reverse
33 5 3 2 1
Link has been destroyed!
---------------------------------------------------
双向链表:
创建,打印,插入,删除,排序,销毁
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *pre;
struct node *next;
}Node,*PNode;
PNode CreatLink()
{
int input;
PNode head,cur,list;
head = (PNode)malloc(sizeof(Node));
head->pre = head->next = NULL;
list = head;
printf("Please input new node:\n");
scanf("%d",&input);
while(input)
{
cur = (PNode)malloc(sizeof(Node));
cur->data = input;
list->next = cur;
cur->pre = list;
list = cur;
scanf("%d",&input);
}
list->next = head;
head->pre = list;
return head;
}
void PrintLink(PNode head)//正序打印
{
PNode list = head;
list = list->next;
while(list != head)
{
printf("%d ",list->data);
list = list->next;
}
puts("");
}
#if 0
void PrintLink(PNode head)//倒序打印
{
PNode list = head;
list = list->pre;
while(list != head)
{
printf("%d ",list->data);
list = list->pre;
}
puts("");
}
#endif
int LenLink(PNode head)
{
PNode list = head;
int len = 0;
list = list->next;
while(list != head)
{
len++;
list = list->next;
}
return len;
}
void DestroyLink(PNode head)
{
head->pre->next = NULL;
PNode list = head;
while(list != head)
{
head = list->next;
free(list);
list = head;
}
}
void InsertLink(PNode head,int input)
{
PNode cur;
cur = (PNode)malloc(sizeof(PNode));
cur->data = input;
cur->next = head->next;
cur->pre = head;
head->next = cur;
cur->next->pre = cur;
}
PNode SearchLink(PNode head,int find)
{
PNode list = head;
list = list->next;
while(list != head)
{
if(list->data == find)
return list;
list = list->next;
}
return NULL;
}
void DeleteLink(PNode pfind)
{
pfind->pre->next = pfind->next;
pfind->next->pre = pfind->pre;
free(pfind);
pfind = NULL;
}
void PopsortLink(PNode head,int len)
{
int i,j;
PNode p,q,tmp;
for(i=0; i<len-1; i++)
{
p = head->next;
q = p->next;
for(j=0; j<len-1-i; j++)
{
if(p->data > q->data)
{
p->pre->next = q;
q->pre = p->pre;
p->pre = q;
p->next = q->next;
q->next = p;
p->next->pre = p;
tmp = p;
p = q;
q = tmp;
}
p = p->next;
q = q->next;
}
}
}
int main()
{
PNode head,pfind;
int len,input,find;
head = CreatLink();
PrintLink(head);
len = LenLink(head);
printf("The len of List is %d\n",len);
printf("Please input new node:\n");
scanf("%d",&input);
InsertLink(head,input);
printf("After insert:\n");
PrintLink(head);
printf("Please input your find:\n");
scanf("%d",&find);
pfind = SearchLink(head,find);
if(pfind == NULL)
{
printf("find none\n");
}
else
{
printf("Your find is %d\n",pfind->data);
DeleteLink(pfind);
printf("After delete:\n");
PrintLink(head);
}
len = LenLink(head);
PopsortLink(head,len);
printf("After sort:\n");
PrintLink(head);
DestroyLink(head);
return 0;
}
运行结果:
Please input new node:
1 2 3 4 5 6 0
1 2 3 4 5 6
The len of List is 6
Please input new node:
99
After insert:
99 1 2 3 4 5 6
Please input your find:
5
Your find is 5
After delete:
99 1 2 3 4 6
After sort:
1 2 3 4 6 99
******************************
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char name[50];
char inputname[50];
char passwd[50];
char inputpasswd[50];
char tmp[50];
FILE *fp;
fp = fopen("data","r");
if(fp == NULL)
{
printf("fopen error");
}
fgets(tmp,50,fp);
while(!feof(fp))
{
if(*tmp == '#')
{
fgets(tmp,50,fp);
continue;
}
else if(*tmp == '[')
{
switch(*(tmp+1))
{
case 'n':
fgets(tmp,50,fp);
strcpy(name,tmp);
break;
case 'p':
fgets(tmp,50,fp);
strcpy(passwd,tmp);
break;
}
fgets(tmp,50,fp);
}
}
fclose(fp);
name[strlen(name)-1] = '\0';
passwd[strlen(passwd)-1] = '\0';
printf("please input name:");
scanf("%s",inputname);
printf("please input passwd:");
scanf("%s",inputpasswd);
while(1)
{
if(strcmp(name,inputname)==0&& strcmp(passwd,inputpasswd)==0)
{
break;
}
printf("please input name:");
scanf("%s",inputname);
printf("please input passwd:");
scanf("%s",inputpasswd);
}
printf("Welcome !!!\n");
return 0;
}