// 函数使用
// 输入:最大最小值
// 输出:范围内所有整数之和
#include <stdio.h>
int main()
{
int add(int,int);// 函数声明
// 自定义函数如果在main后, 在调用前要声明(只注类型即可),否则会提示找不到该函数
// 如果在main前,可不必声明
int a,b;
printf("请输入要求和的区域:\n");
scanf("%d%d",&a,&b); //分别把变量赋值给了a,b
printf("输出求和后的结果:%d\n",add(a,b)); // 调用函数
return 0;
}
int add(int a,int b)
{
int x = a, y = b,sum = 0;
for(;x<=y;x++)
{
sum +=x;
}
return sum;
}
// 函数的递归:调用自身
// 输入一个数 ,求出对应的阶乘,求出结果后打印输出
#include <stdio.h>
#include <stdlib.h>
int main()
{
int div(int); // 函数声明
int n;
long num;
printf("请输入一个整数:\n");
scanf("%d",&n);
num = div(n);
printf("输出%d的阶乘为:%ld\n",n,num);
}
int div(int n) //定义函数
{
// 这里用到exit(0),所以需要导入 库文件
if(n<0)
{
printf("输入数据有误\n");
exit(0);
}
if(n==0||n==1) //0和1的阶乘是1
return 1;
// 递归调用函数自身
else return n*div(n-1);
}
// 结构体
#include <stdio.h>
struct date // data是结构体名
{
int year,month,day; // 结构体成员
};
struct person
{
char name[15];
// 在本结构体中引用另外一个结构体
struct date born;
}p1 = {"Jay",{1888,10,10}};
int main()
{
struct person p2;
printf("请输入p2的信息,依次为姓名,出生年月日:\n");
scanf("%s%d%d%d",&p2.name,&p2.born.year,&p2.born.month,&p2.born.day);
// 输出结构体的p1,p2的信息
printf("%s出生于%d年%d月%d日\n",p1.name ,p1.born.year,p1.born.month,p1.born.day);
printf("%s出生于%d年%d月%d日\n",p2.name ,p2.born.year,p2.born.month,p2.born.day);
return 0;
}
#include <stdio.h>
int main(){
// 如果只需要 stu1 变量,后面不需要再使用结构体名定义其他变量,
// 那么在定义时也可以不给出结构体名
/*struct{ // 在{前没有写结构体名 stu
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1;
//给结构体成员赋值
stu1.name = "Tom";
stu1.num = 12;
stu1.age = 18;
stu1.group = 'A';
stu1.score = 136.5;
//读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
*/
// 定义结构体时同时赋值
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };//这里只对stu2赋值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
return 0;
}
// 结构体数组
#include <stdio.h>
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
int main(){
int i, num_140 = 0;
float sum = 0;
for(i=0; i<5; i++){
sum += class[i].score;
if(class[i].score < 140) num_140++;
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
return 0;
}
// 求结构体大小
// 1. 结构体变量中当前成员的偏移量必须是【当前成员大小】的整数倍(0被认为是任何数的整数倍)
// 2.结构体大小必须是【所有成员】大小的整数倍,也即所有成员大小的公倍数。
// 第n个成员的偏移量=第n-1个成员的偏移量+第n-1个成员的大小(字节) // 结构体大小=最后一个成员的偏移量+最后一个成员的大小
// 对于嵌套的结构体,需要将其展开。对结构体求sizeof时,上述两种原则变为:
// 1. 展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
// 2. 结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。
#include <stdio.h>
struct stu{
char c1;
char c2;
int i;
};
// 嵌套结构体
struct stu5
{
short i;
struct
{
char c; // ss.c的偏移量=4,不是2
int j;
} ss;
int k;
} ;
int main()
{
printf("%d\n",sizeof(struct stu));
// c1的偏移量是0
// c2的偏移量=c1的偏移量+c1的大小=0+1=1,1是c2本身char的整数倍,无须补字符
// i的偏移量=c2的偏移量+c2大小=1+1=2,2不是i本身int的整数倍 ,补2个字符,偏移量为4
// 因此结构体大小=4+4=8
printf("%d",sizeof(struct stu5));//16
return 0;
}
结构体指针的使用
// 结构体指针的使用
// 结构体指针就是指向结构体变量的指针
#include <stdio.h>
int main(){
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
// *pstu = &stu1相当于把stu1的地址幅值给pstu,指针指向地址,所以&
//读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
return 0;
}
结构体数组指针的使用
// 结构体数组指针的使用
#include <stdio.h>
struct stu{
char *name; //姓名 8个字节
int num; //学号 4个字节
int age; //年龄
char group; //所在小组 1个字节
float score; //成绩 4个字节
}stus[] = {
{"Zhou ping", 5, 18, 'C', 145.0},
{"Zhang ping", 5, 18, 'C', 145.0},
}, *ps; // struct定义了两个数据类型,一个是结构体数组stus,一个是指针*ps
int main(){
//求数组长度
int len = sizeof(stus) / sizeof(struct stu);
printf("%d\n",sizeof(stus));//48,这里有2个这样stu的类型,2*24=48
printf("%d\n",sizeof(struct stu)) ;//24
printf("%d\n",len) ;//2
printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
// 用指针变量输出结构数组
// 定义ps为指向stu类型的指针
// 指针变量ps指向一个结构数组stus,这时结构指针变量ps的值是整个结构数组的首地址
// 数组名字stus便是数组的首地址
for(ps=stus; ps<stus+len; ps++){
printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
}
return 0;
}
结构体指针作为函数参数
// 结构体指针作为函数参数
// 计算全班学生的总成绩、平均成绩和以及 140 分以下的人数
#include <stdio.h>
struct stu{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}stus[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
};
int main(){
int len = sizeof(stus) / sizeof(struct stu);
average(stus, len);
return 0;
}
void average(struct stu *ps, int len){ //指针作为函数的参数
int i, num_140 = 0;
float average, sum = 0;
for(i=0; i<len; i++){
sum += (ps + i) -> score;
if((ps + i)->score < 140) num_140++;
}
printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/len, num_140);
}
#include <stdio.h>
union type
{
int cid; //班级
char title[20]; //职称
};
struct Person
{
char name[10]; //姓名
char sex; //性别
int age; //年龄
int flag; //标志是老师还是学生
union type tp;
};
int main()
{
struct Person person[10];
int i;
int num;
char ch;
printf("请输入要录入的人数:\n");
scanf("%d",&num);
for(i = 0;i<num;i++)
{
printf("请输入第%d个人员的信息:\n",i + 1);
printf("姓名: ");scanf("%s",&person[i].name);getchar();
printf("性别: ");scanf("%c",&person[i].sex);getchar();
printf("年龄: ");scanf("%d",&person[i].age);
printf("职业标识符: ");scanf("%d",&person[i].flag);
if(person[i].flag == 0)
{
printf("请输入学生的班级id: ");
scanf("%d",&person[i].tp.cid);
}
else if(person[i].flag == 1)
{
printf("请输入老师的职称: ");
scanf("%s",&person[i].tp.title);
}
else
{
printf("输入有误,请重新输入!\n");
i -= 1;
}
}
printf("\n输出所有录入人员的信息:\n");
for(i = 0;i<num;i++)
{
printf("输出第%d个人员的信息:\n",i + 1);
printf("姓名: ");puts(person[i].name);
printf("性别: ");printf("%c",person[i].sex);
printf("\t年龄: ");printf("%d",person[i].age);
if(person[i].flag == 0)
{
printf("\t学生的班级id: ");
printf("%d\n",person[i].tp.cid);
}
else if(person[i].flag == 1)
{
printf("\t老师的职称: ");
puts(person[i].tp.title);
}
}
return 0;
}
// 枚举
//Mon、Tues、Wed 这些名字都被替换成了对应的数字。这意味着,
//Mon、Tues、Wed 等都不是变量,它们不占用数据区(常量区、全局数据区、栈区和堆区)的内存,
//而是直接被编译到命令里面,放到代码区,所以不能用&取得它们的地址。这就是枚举的本质。
#include <stdio.h>
int main(){
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } day;//枚举值从 1 开始递增
scanf("%d", &day);
switch(day){
case Mon: puts("Monday"); break;
case Tues: puts("Tuesday"); break;
case Wed: puts("Wednesday"); break;
case Thurs: puts("Thursday"); break;
case Fri: puts("Friday"); break;
case Sat: puts("Saturday"); break;
case Sun: puts("Sunday"); break;
default: puts("Error!");
}
return 0;
}
// 类型定义符
#include <stdio.h>
struct Point
{
double x;
double y;
double z;
};
struct Point oPoint1={100,100,0};
// 等价于以下
typedef struct tagPoint
{
double x;
double y;
double z;
} Point;
Point oPoint1={100,100,0};