包含C语言大部分用法代码+注释

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/************************************************
此文件包含大部分C基础的相关内容,注释内不完全对
***********************************************/

#include //添加标准输入输出流头文件

#include //添加字符串处理头文件

#include //添加形参个数不定函数的头文件

#include //添加是否是数字函数的头文件

#include //添加对内存操作的头文件


#define www (a)+(b)//预编译处理

//定义宏
#define H printf(
#define Y "这里是用宏定义来输出的\n");

//下面代码有字定义一样的宏,但是编译不会出现重定义错误.加ifndef endif
#ifndef pppp//如果没有定义
#define HH printf("重定\
义宏测试\n"); //就定义
#endif //结束
#ifndef pppp //如果没有定义
#define HH printf("重定\
义宏测试\n"); //就定义
#endif //结束

//带参数的宏,宏函数
#define SWAP(T,x,y) {T t = x;x = y;y = t;}

#define SWAP1(x,y) {int t = x;x = y;y = t;}


//定义全局变量/数组
//char w[7][10] = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};//定义全局数组

extern char w[7][10];//extern代表是从别的地方定义的

//enum bool{true = 1,false = 0};
////枚举定义,如果没指定数值,第一个为0,依次递增加。如果前面指定值,后面就递增
enum mode{UREAD=0400,UWRITE=0200,UEXEC=0100,GREAD=0040,GWRITE=0020,GEXEC=0010,OREAD=0004,OWRITE=0002,OEXEC=0001};//定义枚举变量
enum course{CPP,JAVA,DOTNET,TEST};
enum gender{MALE,FEMALE};
typedef enum gender sex;//定义别名.也可以定义类型名的同时定义别名如下语句
//typedef enum gender{MALE,FEMALE}sex;

typedef char A[20];//给char[20]起别名A

//定义结构体
struct person{
//A name;//等同于char name[20],注意看上面A的定义。别名
char name[20];//字符数组
sex s;//枚举,注意:有定义过别名
int age;//整型
double income;//双精度浮点数
};

//定义结构体
typedef struct per{
char name[20];//姓名
char gender;//性别
int age;//年龄
double salary;//工资
}pre;//别名

//定义结构体//位段
struct weiduan
{
unsigned char userread:1;//1代表占一位
unsigned char userwrite:1;//1代表占一位
unsigned char userexecute:1;//1代表占一位
unsigned char groupread:1;//1代表占一位
unsigned char groupwrite:1;//1代表占一位
unsigned char groupexecute:1;//1代表占一位
unsigned char otherread:1;//1代表占一位
unsigned char otherwrite:1;//1代表占一位
unsigned char otherexecute:1;//1代表占一位
};//此结构体只占2字节

//定义共用体
typedef union IP//ip地址
{
char i4[4];//4个字符数组
int net;
double d;
}IP;//占8个字节

//函数
//不带返回值的函数,无形参
void fun1()
{
printf("这个函数没有返回值!\n");
}

//带返回值的函数,无形参

int fun2()
{
return 10;//返回值
}

//带形参的函数
int fun3(int a)
{
int b;
b = a * a;
return b;//返回值
}

//清空缓冲区的函数,提前声明,如果函数是在后面定义,必需要在前面有函数的声明
void clear();

//将数字字符转换成大写的字符串
//char* fun_char(char c)
void fun_char(char c)
{
char charnum[10][5] = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};//定义字符串数组
printf("%s\n",charnum[c-'0']);
//return charnum[c-'0'];//返回数组中某个下标的值
}

//返回字符地址的函数
char* weekday(int n)
{
return w[n];
}

//定义一个变量或数组,让其成为静态变量。静态变量只有在程序结束时才释放。用static来定义
//定义一个函数,其函数内部定义静态变量
char* weekday2(int n)
{
static char we[7][10] = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};//静态
return we[n];
}

//掉换两个数据函数,这个函数是调换不了的.函数值传递是不能改实参的值
void swap(int a,int b)
{
int c;
c = a;
a = b;
b = c;
}

//定义一个年、月、日 的结构体
typedef struct date{
int year;
int month;
int day;
}date;

date input()//输入函数
{
date x;
printf("请输入日期,以空格分开\n");
scanf("%d%d%d",&x.year,&x.month,&x.day);//输入
return x;
}

void ouput(date da)
{
printf("%d-%d-%d\n",da.year,da.month,da.day);
}


//数组做为函数的参数
void printttt(int b[],int n)
{
for(int i = 0;i{
printf("%d\n",b[i]);//输出
}
}

//将数组的值颠倒的
void reverse(int b[],int n)
{
int i =0,j=0,k =n-1;
for(i = 0;i{
j = b[i];
b[i] = b[k];
b[k] = j;
k--;
}
}

//定义一个形参个数不定的函数,取一组数据的最大值

int maxxx(int n,...) //添加形参个数不定函数的头文件.注意。至少有一个固定的形参
{
va_list v;//定义一个数量不定的参数表.v保存可变长参数表,va_list是一个类型
va_start(v,n);//开始一个可变参数表.意思是用v保存从n之后的那些参数
int i;
int maxvalue = va_arg(v,int);//存放第一个值.va_arg(v,int)是从参数表中取一个int类型的数据
for(i = 1;iint da = va_arg(v,int);//到得每个数据.第一个参数是参数表,第二个参数是取什么类型的数据va_arg()函数会返回指定类形的数据
if(da>maxvalue)
{
maxvalue = da;
}
}
va_end(v);//释放可变长的参数表
return maxvalue;
}

//递归函数
int f(int x)
{
if(x<=0)
{
return 5;
}
else
{
return 2*f(x-1)+3;
}
}

//递归函数,输出一个整数的每一位
void dec(int n)
{
if(n>9)
{
dec(n/10);
}
printf("%d ",n%10);
}

//地址做为参数的函数
void jiaohuan1(int* in1,int* in2)
{
int q = *in1;

*in1 = *in2;
*in2 = q;
}

//定义指针形参函数
void array(int *q,int n)
{
printf("这样传参数,只传了 %d 个字节的数据!\n",sizeof(q));//只传4个字节数据,因为指针的长度就是固定的4个字节
for(int k = 0;k < n; k++)
{
printf("%d ",q[k]);
}
printf("\n");
}

int str2int(const char* str,const char** q) //**q是传递的二级指针
{
int r = 0;
while(isdigit(*str)) //isdigit()函数是库函数,是用来判断是否是数字.要添加ctype.h
{
r = r*10+*str-'0';//*str是取str所指向的值
++str;//指针后移,指向下一个字符地址
}
*q = str;//通过*q来查找到传过来 保存地址的指针
return r;
}


void voidprint(int* p)
{
printf("%d ",*p);
}

void voidadd(int* p)
{
*p += 10;
}

void voidclear(int* p)
{
*p = 0;
}

void voidfill(int *p)
{
static int staticint = 0;//定义静态变量,运行时注意受这行影响的数值
*p = ++staticint;
}
//用一个函数来代替多次的循环,传值有函数指针
void foreach(int a[],int n,void (*fp)(int*))//void (*fp)(int*)是传函数指针
{
int i;
for(i = 0;i{
(*fp)(a+i);//通过函数指针调用函数
}
}


//数据排序
int rele1(int a,int b)
{
return (a>b);
}
int rele2(int a,int b)
{
return (a}

void sort(int a[],int n,int (*p)(int,int))
{
int i,j;
for(i = 0;i{
for(j=i+1;j{
if(p(a[i],a[j])==1)//P是指针函数,通过函数指针调用
{
SWAP1(a[i],a[j]);//使用宏来对换两个数据,宏前面有定义,这里不好用函数
}
}
}
}

void input1(int a[],int n)
{
int i;
printf("请输入5个整数:\n");
for(i = 0;i{
scanf("%d",a+i);//a+i等同于&a[i]
}
}

void show(int a[],int n)
{
int i;
for(i = 0;i{
printf("%d ",a[i]);//输出
}
printf("\n");
}

//结构体指针传递函数
void printstruct(date const* p)//const在这里的作用是不让通过p指针改变数据
{
printf("%d-%d-%d\n",p->year,p->month,p->day);//输出,p->year等同于(*p).year
}



/*===============================================================================================*/
int main()//主函数
{
aaa: //标记,重复运行

/****最简单的C输出****/
printf("最简单的C输出!==================================================\n");
printf("您好!\n");//输出文字,\n代表换行

/****变量、常量****/
printf("变量、常量!==================================================\n");

//变量名以字母、数字、下划线级成,必需以字母或下划线开始,中间不能有空格
int int1,int2;//定义整型变量,没有初始化赋值,存的是垃圾数据
int int3 = 100,int4 = 201;//定义整型变量并初始化赋值

float float1,float2;//定义单精度变量,没有初始化赋值,存的是垃圾数据
float float3 = 2.0,float4 = 0.2;//定义单精度变量并初始化赋

值,编译错误时都会提示这行有错误,但这行不是错误本身

double double1,double2;//定义双精度变量,没有初始化赋值,存的是垃圾数据
double double3 = 2.1546765,double4 = 5.1654565;//定义双精度变量并初始化赋值

const int const1 = 50;//定义整型常量,常量必需要初始化,与下条语句相同
int const const2 = 20;//定义整型常量,常量必需要初始化,与上条语句相同

char char1,char2;//定义字符变量,没有初始化赋值,存的是垃圾数据
char char3 = 'a',char4 ='b';//定义字符变量并初始化赋值

int i,j;//定义变量,循环时用

/****运算符****/
printf("运算符!==================================================\n");
//算术运算符+,-,*,/,%
printf(" 算术运算符:\n");
printf("2+3 =%d,8-2=%d,5*2=%d,15/3=%d,12%%5=%d\n",2+3,8-2,5*2,15/3,12%5);

//逻辑运算符&&,||,!
printf("逻辑运算符:\n");
printf("1&&1=%d,1&&0=%d,0&&1=%d,0&&0=%d,1||1=%d,1||0=%d,0||1=%d,0||0=%d,!0=%d,!1=%d\n",
1&&1,1&&0,0&&1,0&&0,1||1,1||0,0||1,0||0,!0,!1);

//关系运算符>,>=,<,<=,==,!=
printf(" 关系运算符:\n");
printf("2>1=%d,2>=1=%d,1<2=%d,1<=2=%d,2==2=%d,2!=2=%d\n",
2>1,2>=1,1<2,1<=2,2==2,2!=2);

//按位运算符&,|,^,-,>>,<<
printf("按位运算符:\n");
printf("5&51=%d,5|51=%d,5^51=%d,5>>2=%d,5<<2=%d\n",
5&51,5|51,5^51,5>>2,5<<2);

//三目运算符
printf("三目运算符:\n");
printf("%d\n",5==10?40:50);


/****输入、输出格式控制****/
printf("输入、输出格式控制!==================================================\n");

/********格式符
%i,%d int(整型)
%hd,%ld short(短整型) int/long(长整型) int(整型)
%u unsigend int(无符号整型)
%x 十六进制
%o 八进制
%f float(单精度浮点数)
%lf double(双精度浮点数)
%g double(以短格式输出,不显示后面无意义的0)
%c char(字符)
%s string(字符串)
%p address(地址)
*************/

//输入的控制符也是一样,输入用scanf()
printf("整型=%d,单精度=%f,双精度=%lf,字符=%c\n",int3,float3,double3,char3);

/****循环****/
printf("循环!==================================================\n");
//for
printf("for!==================================================\n");
for(i = 1;i<=6;i++)
{
for(j = 1;j <= i;j++)
{
if(i == 4)
{
continue;//跳出内循环,不执行这个循环内后的面的语句
printf("这行不会被输出\n");
}
printf("%dx%d=%2d%c",j,i,j*i,j!=i?',':'\n');
}
}

//while,先判断,后执行
printf("while!==================================================\n");
int cnt = 1;
while(cnt<=5)
{
printf("输出第 %d 次!\n",cnt);
cnt++;//变量自加,自身赋值
}

//do while,先执行,后判断

printf("do while==================================================\n");
int cnt1,n=0;//
do{
printf("请输入一个

1-9的整数接着运行:\n");
cnt1 = scanf("%d",&n);//从键盘输入,并赋值给变量。判断输入的值是否有效,并赋值给变量cnt
//printf("%d\n",n);
fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin);
}while(cnt1 != 1||n<0||n>9);

/****预编译****/
printf("预编译处理!==================================================\n");
int a =50,b = 60;
printf("使用预编译处理:%d\n",www);//这里的www将换成(a)+(b)

/****枚举****/
printf("枚举输出!==================================================\n");
printf("%d,%d,%d,%d\n",CPP,JAVA,DOTNET,TEST);//使用的是枚举,输出0123
printf("%d,%d,%d,%d,%d,%d,%d,%d\n",UREAD,UWRITE,UEXEC,GREAD,GWRITE,GEXEC,OREAD,OWRITE,OEXEC);//使用的是枚举

/****判断语句switch****/
printf("判断语句!==================================================\n");
//if
if(a==50)
{
printf("if语句输出!\n");//这行会执行
}
if(a!=50)
{
printf("if语句输出!\n");//这行不会执行
}

//if else
if(a == 60)
{
printf("if语句输出!\n");//这行不会执行
}
else
{
printf("if语句输出!\n");//这行会执行
}

//if else if else
if(a == 60)
{
printf("if语句输出!\n");//这行不会执行
}
else if(a == 50)
{
printf("if语句输出!\n");//这行会执行
}
else
{
printf("if语句输出!\n");//这行不会执行
}

/****选择语句switch****/
printf("选择语句!==================================================\n");
printf("输入0-3的整数:\n");
int switch_n;
scanf("%d",&switch_n);
fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin);

switch(switch_n)
{
case CPP:
puts("输出CPP");
break;//跳出switch
case JAVA:
puts("输出JAVA");
break;
case DOTNET:
puts("输出DOTNET");
break;
case TEST:
puts("输出TEST");
break;
default:
puts("输入无效值");
}

/****输出一个整数的二进制****/
printf("输出一个整数的二进制!==================================================\n");
const int bits = sizeof(int)*8;//sizeof()是获取字节数
unsigned int mask = 1<int e=0,k,e1;
puts("请输入一个整数:");
scanf("%d",&e);
e1 = e;
fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin);
printf("%d的二进制是:\n",e);
for(k=0;k{
printf("%c",e&mask?'1':'0');
mask = mask>>1;//右移1位自身赋值
}
//以下也是一样的输出
printf("\n");
for(k=0;k{
printf("%c",e<0?'1':'0');
e=e<<1;//左移1位自身赋值
}
//以下也是一样的输出
printf("\n");
for(k=0;k{
printf("%d",e1<0);
e1=e1<<1;//左移1位自身赋值
}
printf("\n");

/****数组****/
printf("数组操

作!==================================================\n");
//数组名是表示第一个元素的地址
int arr[10];//定义一个有十个元素的数组,[]内是数组元素的个数,非负数。没有赋初始值
arr[0] = 100;//给数组arr的第一个元素赋值.
*arr = 200;//也是给arr数组的第一个元素赋值
printf("输出数组第一个元素的值%d\n",arr[0]);//arr[0]是读取数组的第一个元素的的值

int in;
printf("请输入十个整数:\n");
/*for(in = 0;in<10;in++)
{
scanf("%d",&arr[in]);//键盘输入并赋值给变量,in是数组的下标,下标一定不能越界
}*/
//==============================================================
//输入也可以用下面的for
for(in = 0;in<10;in++)
{
scanf("%d",arr+in);//arr+i,相当于从第一个元素开始加数组数据类型的字节数*in。都是取得各变量的地址
}

fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin);
/*for(in = 0;in<10;in++)
{
printf("您刚才输入的第%d个整数是:%d\n",in+1,arr[in]);
//arr[in]也可以写成in[arr],但是不应该这么使用,代码可读性不好
}*/
//===========================================================
//输出数组也可以用下面的for
for(in = 0;in<10;in++)
{
printf("您刚才输入的第%d个整数是:%d\n",in+1,*(arr+in));//*(arr+in)其实就是通过地址查找变量获取变量值
//*(arr+in)也可以写成*(i+arr)
}

int arr2[4] = {100,521,452,86};//定义数组并初始化赋值
//输出数组
printf("输出数组:\n");
for(in =0;in<4;in++)
{
printf("数组的第%d个的值是:%d\n",in+1,arr2[in]);
}

char charr[4] = {'A','B','C','D'};//定义字符数组,注意:不是字符串
//printf("%s\n",charr);//可能输出ABCD后面会有乱码
char charr1[8] = {'h','e','l','l','o','\0','w','o'};
printf("%s\n",charr1);//只会输出hello,后面的不会输出,因为字符串遇到\0会结束

char str[100];//定义字符串数组
printf("请输入一个100个字符以内的字符串:\n");
scanf("%s",str);//输入字符串,当遇到空格时结束。这行写成scanf("%s",&str);也是一样的效果,一般不会对数组名取地址
//gets(str);//输入的是一行字符串,遇到回车键里才结束,但是使用gets(),会有超界的风险.建议不要使用
printf("%s\n",str);//输出字符串
char str1[100] = "abcdefghi";//字符数组可以直接通过字符串来初始化.如是[]内写10的话,xp系统下退出是不会报错,但在WIN8下是不可的,会有内存溢出错误
printf("%s\n",str1);//输出字符串

printf("%c\n","sai12045"[2]);//字符串相当于没有名字的字符数组,以\0结尾.此行会输出一个字符i

//str1 = "dakkdskfkaf";//这样是不允许的,数组可以初始化,但不能给数组名赋值,因为数组名是数组的首地址
//可以用函数来实现,将字符

串赋值给数组

/****字符串操作****/
printf("字符串操作!==================================================\n");
strcpy(str1,"qlkq rjqworoqwrqwir");//这样就把后面的字符串赋值给了数组str1 .记得添加string.h头文件
printf("%s\n",str1);
strcat(str1,"AAAAAAAAAAAAAAAAA");//在字符串未尾追加字符串.记得添加string.h头文件
puts(str1);//输出字符串
printf("字符串的长度是:%d\n",strlen(str1));//strlen()是获取字符串的长度,记算结果不包括\0
printf("%s\n",strchr(str1,'o'));//strchr()在函数中查找字符,返回找到字符的地址,如果没找天返回空地址null
printf("%s\n",strstr(str1,"oqw"));//strstr()在函数中查找字符串,返回找到字符串的地址,如果没找天返回空地址null
//strcmp()函数可对比两个字符串的大小,它是一个一个比ASCLL码,比到不同结束

/****二维数组****/
printf("二维数组!==================================================\n");
int arr3[3][4] = {0};//定义二维数组并初始化全部为0
int arr4[3][4] = {{10,20,30,40},{101,102,103,104},{250,251,252,253}};//定义二维数组并初始化
//输出二维数组
for(i = 0;i <3;i++)
{
printf("%#p\n",arr4[i]);//输出地址
for(j = 0;j < 4;j++)
{
printf("%d ",arr4[i][j]);//输出数据
}
printf("\n");//输出换行
}

char chararr2[3][20] = {"张三","李四","王五"};//定义字符二维数组
for(i = 0;i<3;i++)
{
printf("%s,",chararr2[i]);//输出
}
printf("\n");


/****结构体****/
printf("结构体!==================================================\n");
person per1;//定义结构体变量,没有初始化赋值
person per2 = {"陈良陈",MALE,80,8000};//定义结构体变量并初始化赋值
//输出
printf("%s是一位年方%d的%s,月薪%lf\n",,per2.age,per2.s==MALE?"帅哥":"美女",per2.income);//用.号可以访问结构体中的数据
person per3 = per2;//对象直接赋值
// = "陈权权";//给对象成员赋值.这们会出错,是不行的,因为name是数组.用以下语句可以
strcpy(,"陈权权");//给对象成员赋值,用函数strcpy是可以赋值的
per1.age = 35;//给对象成员赋值
per1.s = FEMALE;//给对象成员赋值
per1.income = 83564;//给对象成员赋值
person perarr[5];//定义结构体数组

/****位段****/
//参见前面的位段定义
printf("位段!==================================================\n");
struct weiduan wei={1,1,0,1,0,0,1,0,0};
//输出
printf("%d%d%d,%d%d%d,%d%d%d\n",
erread,erwrite,erexecute,wei.groupread,wei.groupwrite,wei.groupexecute,
wei.otherread,wei.otherwrite,wei.otherexecute);

/****共用体****/
//参见前面的共用体定义
printf("共用体!==================================================\n");
printf("输出大小:%d\n",sizeof(IP));
IP meip = {192,168,2,234};//定义共用体变量
printf("%x\n",m

);//注意输出字节序

= 0x12345678;
printf("%d,%d,%d,%d\n",meip.i4[0],meip.i4[1],meip.i4[2],meip.i4[3]);//注意输出字节序


/****函数****/
//函数有前面有定义
printf("函数!==================================================\n");
//调用函数
fun1();//调用函数
int fun_return;
fun_return= fun2();//调用带返回值的函数
printf("%d\n",fun_return);//输出
fun_return = fun3(45);//调用带形参的函数
printf("调用带有形参的函数,返回值是:%d\n",fun_return);
clear();//调用清空输入缓冲区函数。注意函数的声明与定义
fun_char('2');//调转换成大写字符串的函数
printf("%s\n",weekday(5));//调用返回值为字符地址的函数
printf("%s\n",weekday2(3));//调用带有静态变量的函数

//寄存器变量,将数据存在器存中,能最快速的访问
register int rerint;//定义寄存器变量
for(rerint = 0;rerint < 5;rerint++)
{
printf("寄存器存储+%d\n",rerint);//
}

//调对换两个数的函数
int mn = 10;
int mm = 20;
printf("调用函数之前mn = %d,mm = %d\n",mn,mm);
swap(mn,mm);//调用函数,这个函数不能对换这两个数
printf("调用函数之后mn = %d,mm = %d\n",mn,mm);

date date1 = {2010,12,25};//定义结构体变量
ouput(date1);//调用输出日期函数
//clear();//调用清空缓冲区函数
date1 = input();//调用输入日期函数
ouput(date1);//调用输出日期函数

int intarra[6] = {100,200,300,400,500,600};//定义整型数组
printttt(intarra,6);//调用数组名做为参数的函数,输出
reverse(intarra,6);//调用将数组调换的函数
printf("数据调换之后输出:\n");
printttt(intarra,6);//调用数组名做为参数的函数,输出

printf("最大值是:%d\n",maxxx(2,56,89));//调用形参个数不定的函数
printf("最大值是:%d\n",maxxx(6,56,70,75,52,12,20));//调用形参个数不定的函数

printf("调用递归函数:%d\n",f(3));//调用递归函数
dec(45278);//调用递归函数
printf("\n");

/****宏****/
printf("宏!==================================================\n");
H Y;//使用宏,宏就是替换
HH //使用宏.在行尾加\,代表是续行符,表示与下一行连接

//系统自带的宏,__是两个下划线
puts(__FILE__);//系统自带的宏.文件路径
printf("%d\n",__LINE__);//系统自带的宏,行号。只有这个是整数。别的都是字符串
puts(__DATE__);//系统自带的宏。日期
puts(__TIME__);//系统自带的宏。时间
//puts(__STDC__);//系统自带的宏,这个很少用

//带参数的宏.宏函数
int hong1 = 10,hong2 = 20;
double hong3 = 12.031,hong4 =451.125;
SWAP(int,hong1,hong2);//使用带参数的宏
SWAP(double,hong3,hong4);//使用带参数的宏
printf("%d,%d\n",hong1,hong2);
printf("%f,%f\n",hong3,hong4);


/****指针****/
printf("指针!===========================================

=======\n");
int* intz1;//定义int类型的指针变量,未赋初始值。野指针,最好不要有野指针,程序不安全。如是赋值有可能会导致程序崩溃
double* doublez1;//定义int类型的指针变量,未赋初始值.野指针
int inti1 = 1000;//定义整形变量
intz1 = &inti1;//给指针变量赋值
double doubled1 = 124.256;//定义浮点类型变量
doublez1 = &doubled1;//给指针变量赋值
//用指针变量输出
printf("%d,%f\n",*intz1,*doublez1);//*表示取地址中的变量值

char chararr3[8] = {'a','b','c','d','e','f','g','h'};//定义字符类型数组
char* charp1 = &chararr3[0];//定义字符类型变量指针并初始化
char* charp2 = &chararr3[2];//定义字符类型变量指针并初始化
char* charp3 = chararr3;//用数组名给指针赋值是对的,因为数组名就相当数组的首地址
//用指针变量输出
printf("%c,%c\n",*charp1,*charp2);//*表示取地址中的变量值
printf("%c\n",(charp3+2)[1]);//(charp3+2)[1]等同于*((charp3+2)+1)等同于*(charp3+3)等同于charp3[3]
//以下两个for输出是一样的
for(i = 0;i < 8;i++)
{
printf("%c",*(charp3+i));//用取地址+i输出。地址+i,代表以i为下标的元素.也可以charp3++
}
printf("\n");
for(i = 0;i < 8;i++)
{
printf("%c",charp3[i]);//用取地址+i输出。地址+i,代表以i为下标的元素.也可以charp3++
}
printf("\n");
*charp1 = 'A';//通过指针变量给字符变量赋值,*表示取地址中的变量
*charp2 = 'B';//通过指针变量给字符变量赋值,*表示取地址中的变量
//用指针变量输出
printf("%c,%c\n",*charp1,*charp2);//*表示取地址中的变量值

int* intp2 = NULL;//表示空地址,尽量使用这种方式,不要有野指针
int intx1 = 2000,intx2 = 3000;//定义两个整形变量
int* intp1 = 0;//表示空地址,尽量使用这种方式,不要有野指针
intp1 = &intx1;//指针变量赋值
intp2 = &intx2;//指针变量赋值
//通过传地址做为函数型参,交换两个变量的值
jiaohuan1(intp1,intp2);//调用传地址的函数
printf("%d,%d\n",intx1,intx2);//输出交换之后变量的值

int arrayint[5] = {101,102,103,104,105};//定义数组
array(arrayint,5);//调用数组名传给指针的函数

int * const coni =arrayint;//定义常量指针,常量指针必须在定义时赋值.const在*号右边
const int* cona = arrayint;//定义不能通过此指针去更改数据.const在*号左边
int const * conb = arrayint;//定义不能通过此指针去更改数据.const在*号左边

char* names[5] = {"张三三","李四四","王五五","韦六六","胡七七"};//定义字符指针数组.只保存了5个地址,并不是保存5个字符串
for(i = 0;i<5;i++)
{
printf("感谢%s来参加!\n",names[i]);//输出。names指针数组保存的是每个字符串的首地址
}

const int ina = 50,inb = 20, inc = 60, ind =40,ine = 80, inf =30;//定义常量

const int* inp[6] = {&ina,&inb,&inc,&ind,&ine,&inf};//定义常量指针数组。明确规定不能通过此指针更改任何数据
//对上面的数据进行排序
for(i =0;i<6;i++)
{
for(j = i+1;j<6;j++)
{
if(*inp[j]<*inp[i])//如果后面的数据比前面的数据小,那么就交换这两个指针
{
const int * inx = inp[j];//这里必须要加const
inp[j] = inp[i];
inp[i] = inx;
}
}
}
printf("输出排序之后的数据:\n");
for(i = 0;i<6;i++)
{
printf("%d ",*inp[i]);
}
printf("\n");

//二级指针
int intaa = 654321;//定义整形变量
int* intbb = &intaa;//定义整形指针并初始化
int** intcc = &intbb;//定义二级指针,并赋值
**intcc = 123456;//通过二级指针赋值
printf("%d\n",**intcc);//通过二级指针输出数据

const char* charp = NULL;
int intq = str2int("987456abcdekddf",&charp);//函数调用
printf("%d,%s\n",intq,charp);//输出

int (*pin)[5];//*pin是指针,指向5个元素的int数组
int intarray[5] = {12,34,56,78,90};//int数组
//pin = intarray;//赋值,是错误的
pin = &intarray;//赋值,这样才是对的.pin是指针,是用来保存数组地址的
for(i =0;i<5;i++)
{
printf("%d ",(*pin)[i]);//(*pin)[i]等同于*(*pin+i),也相当于x[i],
}
printf("\n");

int intarray1[3][5] = {{1,2,3,4},{5,6,7},{8,9}};//定义int二维数组,二维数组名等同于指向数组的指针
pin = intarray1;//这样赋值是可以的。数组名intarray1是表示intarray1[0]的地址,相当于int[5]的地址
for(i = 0;i<3;i++,printf("\n"))//注意这里面有一个输出换行, 这个换行就是每输出一组数据换一行
{
for(j = 0;j<5;j++)
{
printf("%d ",pin[i][j]);//输出.pin[i][j]等同于intarrat1[i][j],也等同于*(*(pin+i)+j)
}
}

int (*pnn)(char);//pnn是指针,指向一个形参为char返回值是int的函数,本程序中,此行代码没有使用
int (*pnp)();//pnp是指针,指向一个形参为任意返回值是int的函数
pnp = &main;//将main函数的地址赋值给pnp指针
printf("%p\n",pnp);//输出pnp的地址

int intarray2[5];//定义int数组
for(i = 0;i<5;i++)
{
voidfill(intarray2+i);//调用函数,这个函数会给数组赋值
}
//输出
for(i = 0;i<5;i++)
{
voidprint(intarray2+i);//调用函数输出
}
printf("\n");

for(i = 0;i<5;i++)
{
voidadd(intarray2+i);//调用函数
}
//输出
for(i = 0;i<5;i++)
{
voidprint(intarray2+i);//调用函数输出
}
printf("\n");

for(i = 0;i<5;i++)
{
voidclear(intarray2+i);//调用函数
}
//输出
for(i = 0;i<5;i++)
{
voidprint(intarray2+i);//调用函数输出
}
printf("\n");

//注意运行以下代码后输出的是6 7 8 9 10,这里要清楚是什么回事
for(i = 0;i<5;i++)
{
voidfill(intarray2+i);//调用函数
}
//输出
for(i = 0;i<5;i++)
{
voidprint(intarray2+i);//调用函数输出
}
printf("\n");

int

intarray3[5];//定义int数组
foreach(intarray3,5,voidfill);//通过传函数名来调用函数
//输出,效果和上面一样
foreach(intarray3,5,voidprint);//通过传函数名来调用函数,输出
printf("\n");

foreach(intarray3,5,voidadd);//通过传函数名来调用函数
//输出,效果和上面一样
foreach(intarray3,5,voidprint);//通过传函数名来调用函数,输出
printf("\n");

foreach(intarray3,5,voidclear);//通过传函数名来调用函数
//输出,效果和上面一样
foreach(intarray3,5,voidprint);//通过传函数名来调用函数,输出
printf("\n");

foreach(intarray3,5,voidfill);//通过传函数名来调用函数
//输出,效果和上面一样
foreach(intarray3,5,voidprint);//通过传函数名来调用函数,输出
printf("\n");

int ainput[5];//定义整形数组
clear();//调用清空缓冲区函数
input1(ainput,5);
sort(ainput,5,&rele1);//传函数的地址作为参数,调用排序函数
printf("从小到大排序后输出:");
show(ainput,5);//调用输出函数

sort(ainput,5,&rele2);//传函数的地址作为参数,调用排序函数
printf("从大到小排序后输出:");
show(ainput,5);//调用输出函数

date datea[3] = {{2010,12,21},{2015,9,24},{2012,6,30}};//定义结构体数组织
for(i = 0;i<3;i++)
{
printstruct(&datea[i]);//将结结构体指针作为传递.输出
}

//动态内存的申请与释放
double* malldouble = (double*)malloc(sizeof(double));//申请一个double类型的内存空间,返回指针.注意加头文件.(double*)是用来转换的,否则出错
int* callint = (int*)calloc(5,sizeof(int));//申请5个int类型的数据内存空间,相当于数组
printf("malldouble = %p,callint = %p\n",malldouble,callint);//输出地址值

//存放数据到申请的空间
*malldouble = 1234.567;//赋值
for(i = 0;i<5;i++)
{
callint[i] = i+10;//赋值
}
printf("malldouble = %g\n",*malldouble);
for(i = 0;i<5;i++)
{

printf("callint%d = %d ",i,callint[i]);//输出
}
printf("\n");

//释放申请的内存空间
free(malldouble);//如果不释放空间,只有等程序结束时才会释放申请的内存空间

//重新分配空间
//realloc(callint,0);//如果这样写,就相当于把申请的空间释放了
callint = (int*)realloc(callint,sizeof(int)*10);//重新分配空间,sizeof(int)*10是分配后的空间大小,它会把之前的数据保留

//申请空间检查是否成功
if(callint == NULL)
{
printf("申请的内存空间失败\n");
}
//分配之后输出
for(i = 0;i<10;i++)
{

printf("callint%d = %d ",i,callint[i]);//输出
}
printf("\n");

callint = (int*)realloc(callint,0);//释放空间
printf("释放后输出%p\n",callint);//释放之后输出

/****IO操作****/
printf("IO操作!==================================================\n");

int intio = 0;
double doubleio = 0;//如是这里不初始化,WIN8运

行时会报错
char chario[100];
//下面这行有输出缓冲,如果后面没有fscanf,不会立即显示,但是在这里看不出来。如果想让它立即显示,可以用stderr
fprintf(stdout,"请输入姓名,年龄,体重:\n",chario,intio,doubleio);//fprintf是从文件读取数据,但在这里用跟printf是一样的
fprintf(stderr,"请输入姓名,年龄,体重:\n",chario,intio,doubleio);//立即显示,无缓冲
fscanf(stdin,"%s%d%lf",chario,&intio,&doubleio);//fscanf是从文件读取数据,但在这里用跟scanf是一样的
fprintf(stdout,"刚才输入的姓名是:%s,年龄是:%d,体重是:%lf\n",chario,intio,doubleio);
//stdin是标准输入,stdout标准输出,stderr标准错误

//打开文件
printf("即将打开test.txt文件,如果文件不存在,程序会直接退出!请输入任意一个字符继续:\n");
char abce;
clear();//调用函数清空键盘缓冲区
scanf("%c",&abce);
FILE* openfi = fopen("test.txt","r");//打开文件,打开文件时注意文件要存在并且有权限
//查检打开是否成功,打开文件必需要查检
if(openfi == NULL)//检查是否成功。以写的方式打开文件,文件可以不存在
{
printf("打开文件失败!");
return 1;
}
//读文件
fscanf(openfi,"%s",chario);//读文件到赋值给变量
fscanf(openfi,"%d%lf",&intio,&doubleio);//读文件到赋值给变量
//关闭打开的文件
fclose(openfi);//关闭打开的文件
printf("从文件读出的数据是:%s,年龄是:%d,体重是:%g\n",chario,intio,doubleio);

//写文件
FILE *openxie = fopen("out.txt","w");//写文件。打开一个文件,打开的目的是写
if(openxie == NULL)
{
printf("打开文件失败!");
return 1;
}
//写入文件
fprintf(openxie,"将文件写入数据!\n");
fprintf(openxie,"姓名:%s, 年龄是:%d, 体重是:%lf\n",chario,intio,doubleio);
fclose(openxie);//关闭文件
printf("已经写入文件到out.txt,请查看!\n");

//gets()是从键盘读取一行,读到换行符为止,丢弃换行符
//puts()是输出一行到屏幕,自动会加换行符
//fgets()是从文件读取一行,保留换行符作为字符串的一部分
//fputs()是将一行文字写入到文件,会自动将换行符转换成\0\n存储
//scanf("%[^\n]%*c",str)是读取一行,到换行符为止。%*c是丢弃一个字符,这里是代表把换行符丢弃掉,str是字符数组
//fgets(but,sizeof(but),stdin)//but是字符数组名,sizeof(but),stdin是表示从键盘读。第三个参数可以是文件指针。会读取换行符存储到数组中
//but[strlen(but)-1] = '\0';是将but字符数组的最后一个字符设置为\0
//fputs(but,stdout) but是字符数组,stdout是输出到屏幕。也可以输出到文件。fputs不会自动增加换行符
//getchar/putchar == scanf("%c",字符变量)/printf("%c",字符变量) 都是对键盘或屏幕 读取或显示一

个字符
//fgetc/fputc getc/putc 作用是一样的,都是对文件读取或写入一个字符。只不过getc/putc有可能是用宏来实现
//以上两行,对所有字符都会读取。可通过判断是否已经读到末尾,方法是判断读取的字符是否==EOF


//又读又写文件。请打开目录下的a2z.txt文件查看程序运行前与运行后的变化
/*下面的代码WIN8下没有达到预期的效果,如文件里的内容是abcdefgh,那么程序运行完后应该是aacceegg
FILE* fpok = fopen("a2z.txt","r+");//r+是以读写的方式打开
if(fpok == NULL)
{
printf("无法打开文件!");
return 1;//如果打开不成功,程序会退出。将不执行后面的操作
}
int intc;
while((intc=fgetc(fpok)) != EOF)//用fgetc来读取,只要读取没到文件结尾
{
printf("%c",intc);
fputc(intc,fpok);//写入文件
}
fclose(fpok);//关闭打开的文件
*/

//文件定位与读写,打开文件jiao.txt,第十个字符与第二十个字符对换
FILE* fphuan = fopen("jiao.txt","r+");
if(fphuan == NULL)
{
printf("打开文件jiao.txt不成功!");
return 1;
}
fseek(fphuan,9,SEEK_SET);//定位到文件的第十个字符,中间数字是代表偏移量。SEEK_SET代表从文件头开始算起
char c10,c20;
c10 = fgetc(fphuan);//读取一个字符,赋值给变量。当前位置为向后移动一个字符
fseek(fphuan,9,SEEK_CUR);//再向后定位。9是偏移量,SEEK_CUR是表示从当前位置算起
c20 = fgetc(fphuan);//读取一个字符,赋值给变量。当前位置为向后移动一个字符
fseek(fphuan,-11,SEEK_CUR);//再向定位。-11是偏移量,SEEK_CUR是表示从当前位置算起
putc(c20,fphuan);//写入字符到文件
fseek(fphuan,-7,SEEK_END);//再向定位。-8是偏移量,SEEK_END是表示从末尾算起
putc(c10,fphuan);//写入字符到文件
fclose(fphuan);//关闭文件
//注意运行完发生的变化

//写入一块数据
//fread/fwrite(内存地址,每个元素字节数,元素个数,文件)
//在前面有定义结构体
per perxx[5] = {{"张三",'F',18,123.4},{"李四",'F',19,231.21},{"王五",'M',20,781.13},{"陈六",'M',21,891.45},{"余七",'F',21,469.321}};//定义结构体变量数组
//打开文件pre.dat
FILE* fppre = fopen("pre.dat","wb");
if(fppre == NULL)
{
printf("打开文件pre.dat文件失败!");
return 1;
}
int intary[10] = {11,22,33,44,55,66,77,88,99,1010};
short shorta = 1234;//定义短整形变量
//写入文件
fwrite(perxx,sizeof(pre),5,fppre);//perxx数组名,是内存的首地址
fwrite(intary,sizeof(int),10,fppre);//intary数组名,是内存的首地址
fwrite(&shorta,sizeof(short),1,fppre);
fclose(fppre);//关闭文件
//注意文件写入之后的效果,除了字符之外,别的都看不懂

//读取一块数据
per perra[5] = {};//定义数组,初始化 全0
int intbry[10] = {0};//定义数组,初始化 全0
sh

ort shortra = 0;
FILE* fpperra = fopen("pre.dat","rb");
if(fpperra == NULL)
{
printf("打开文件pre.dat失败!");
return 1;
}
fread(perra,sizeof(pre),5,fpperra);//读文件块
fread(intbry,sizeof(int),10,fpperra);//读文件块
fread(&shortra,sizeof(short),1,fpperra);//读文件块
fclose(fpperra);//关闭文件
for(i = 0;i<5;i++)
{
printf("姓名:%s,性别:%s,年龄:%d,工资:%g\n",
perra[i].name,perra[i].gender=='M'?"男":"女",perra[i].age,perra[i].salary);//输出
}
for(i = 0;i<10;i++)
{
printf("%d ",intbry[i]);
}
printf("\n%d\n",shortra);

//判断用户输入
printf("请输入任意字符,输入%%号退出循环:");
char strchar[500];
double doubleuser;
register int strc;//register是寄存器,不一定要用
for(;;)
{
strc = getchar();//读取一个字符
if(strc == '%')
{
break;//退出循环
}
if(isspace(strc))//也可以用isblank(),相对于isspace()判断的字符要少一些
{
continue;//如果是空格或者,直接跳过
}
ungetc(strc,stdin);//ungetc是把一个已经读了的字符退回去。如果没有这行,就得不到预期的效果
if(strc>='0' && strc<='9')
{
scanf("%lf",&doubleuser);
printf("浮点数:%lf\n",doubleuser);
}
else
{
scanf("%s",&strchar);
printf("字符串:%s\n",strchar);
}

}

//feof(FILE*)是用来检查读取是否超越了文件末尾
//fread()会返回成功读取到的元素个数



printf("\a");//这是输出响铃
printf("是否还要运行!==================================================\n");
printf("请输入一个字母 r 返回开始处运行!输入其它退出\n");
char ch;
clear();//清空缓冲区
fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin),(如果没有这行,WIN8下运行错误);
scanf("%c",&ch);
clear();//清空缓冲区
//getchar();//从键盘读取一个整数
fflush(stdin); //适用于windows清空缓冲区,但是这样用不保险。也可以使用rewind(stdin);
if(ch == 'r')
{
goto aaa;//返回到aaa处运行,goto是跳转
}


printf("退出==================================================\n");
puts("请按任意键退出!");//puts是自动带换行的输出
/*******************************************************************/
return 0;//主函数返回
}

//清空缓冲区的函数定义,前面有声明,如果函数是在后面定义,必需要在前面有函数的声明
void clear()
{
scanf("%*[^\n]");
scanf("%*c");
}

//char w[7][10] = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};//这个数组在前面有定义

相关文档
最新文档