从基础到实战:C 语言 main 函数传参和结构体使用教程
一、主函数传参
int main(void);
void main(void);
int main(int argc, const char *argv[]);
int main(int argc, const char **argv); //常用写法
#include<stdio.h>
int main(int argc, const char **argv)
{
int i = 0;
printf("argc = %d\n", argc);
for(i = 0; argv[i] != NULL; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
#if 0
for(i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
#endif
return 0;
}
- argc: 传入参数的个数;(个数至少为1,因为第一个参数默认是程序的可执行文件名)
- argv:是一个指向字符串数组的指针,数组中的每一个元素都是一个命令行参数字符串的首地址
二、构造数据类型
1.结构体
(1)类型定义
struct 结构体名
{
数据类型1 成员变量1;
数据类型2 成员变量2;
数据类型3 成员变量3;
...
};
示例:
struct book
{
char name[32];
char author;
int date;
};
struct date
{
int year;
int month;
int day;
};
struct bookdate
{
struct book b;
struct date d;
}; //嵌套结构体类型定义
注意:类型定义时不能赋值
(2)变量的定义
数据类型 变量名
示例:
struct book a;
//这里的a是一个struct book类型的变量,包含了 name,author,date三个成员
(3)变量初始化
- 全部初始化:按成员顺序全部赋值
struct student a = {"LiMing", 'm', 20, 98};
- 局部初始化:用.成员名局部赋值,没有赋值的成员均会被初始化成0值
struct student a ={
.name = {"LiMing"},
.age = 20;
};
struct bookdate bd = {
.b = {
.name = {"LiMing"}
},
.d = {
.month = 5,
.day = 20,
},
};
(4)结构体成员的访问
- 变量访问:用 . 运算符访问
struct student a ={
.name = {"LiMing"},
.age = 20;
};
printf("%s", a.name);
printf("%d", a.age);
- 指针访问:用 -> 运算符访问
struct student a ={
.name = {"LiMing"},
.age = 20;
};
int *p = NULL;
p = &a;
printf("%s\n", p->name);
printf("%d\n", p->age);
注意:不论是变量访问还是指针访问,最终的类型是由成员变量的类型决定的
(5)结构体的内存对齐
CPU读取数据时,会按固定的字长(如4字节、8字节)从对齐的地址读取。如果数据未对齐,CPU需要分两次读取并拼接,会降低效率。
- 结构体成员变量只能存放在内存地址为自身类型长度的整数倍的内存单元中
- 整个结构体的总大小,必须为最大基本类型长度的整数倍
struct a
{
char a; //a占1字节,为了让b按4字节对齐,需在a后再补3个字节,即1+3 = 4个字节
int b; //4字节,即4+4 = 8个字节
short c; //2字节,到目前一共8+2 = 10个字节,但该函数体最大基本类型占4个字节,最 终大小要占4的整数倍,需再补2字节,即为10+2 = 12字节
};
//总大小为12字节
(6)函数体作为函数参数
void fun(struct data a);
//传值传递:会拷贝整个结构体,效率较低,适合小型结构体
void fun(struct date *pa);
//传指针传递:只拷贝地址,效率高,适合大型结构体struct date fun(void);
//返回结构体:函数可以直接返回一个结构体变量
示例:
1.封装一个函数从终端接收年月日信息
2.封装一个函数判断是否为闰年
3.封装一个函数传入年月日返回该天为该年的第几天
#include<stdio.h>
struct date
{
int year;
int mon;
int day;
};
void GetDate(struct date *pday)
{
scanf("%d", &pday->year);
scanf("%d", &pday->mon);
scanf("%d", &pday->day);
return;
}
int LeapYear(struct date *pday)
{
if((0 == (pday->year) % 4)&&((pday->year) % 100 != 0) || ((pday->year) % 400 == 0))
{
return 1;
}
else
{
return 0;
}
}
int YearDay(struct date *pday)
{
int a[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
int b[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
int i = 0;
int sum = 0;
if(LeapYear(pday) == 1)
{
for(i = 0; i < (pday->mon)-1; i++)
{
sum += a[i];
i++;
}
}
else
{
for(i = 0; i < (pday->mon)-1; i++)
{
sum += b[i];
i++;
}
}
sum += pday->day;
return sum;
}
int main(void)
{
int ret = 0;
struct date a = {0};
int Sum = 0;
int Sub = 0;
GetDate(&a);
printf("\n");
ret = LeapYear(&a);
printf("%d\n",ret);
Sum = YearDay(&a);
printf("为该年的第%d天\n",Sum);
return 0;
}
(7)结构体数组
- 定义:
数据类型 数组名[元素个数];
struct student s[3];
- 初始化:
strust student s[3] = {
{"zhao",'m',20,98},
{"qian",'f',21,88},
{"li",'f',21,88},
}
- 打印访问:
void PrintfStudent(struct student *pstu, int len)
{
int i = 0;
for(i = 0; i < len; i++)
{
printf("姓名:%s\n", pstu[i].name);
printf("性别:%c\n", pstu[i].sex);
printf("年龄:%d\n", pstu[i].age);
printf("成绩:%d\n", pstu[i].score);
}
练习:构造一个学生类型的结构体,接收信息(<=5),打印出成绩最低的姓名
#include<stdio.h>
struct student
{
char name[32];
char sex;
int age;
int score;
};
int GetAllStuInfo(struct student *pa, int maxlen)
{
int i = 0;
int cnt = 0;
scanf("%d",&cnt);
for(i = 0; i < cnt; i++)
{
scanf("%s", pa[i].name);
scanf(" %c", &pa[i].sex);
scanf("%d", &pa[i].age);
scanf("%d", &pa[i].score);
}
return cnt;
}
void PrintLastStuName(struct student *pa, int curlen)
{
int i = 0;
int min = 0;
for(i = 1; i < curlen; i++)
{
if(pa[i].score < pa[min].score)
{
min = i;
}
}
printf("成绩最低的是:%s\n", pa[min].name);
return;
}
int main(void)
{
int len = 0;
struct student a[5] = {0};
len = GetAllStuInfo(a,5);
PrintLastStuName(a,len);
return 0;
}
更多推荐


所有评论(0)