// 定义结构体类型
typedef struct {
int num; // 学号
char name[20]; // 姓名
char gender; // 性别
float score; // 分数
} Student;
// 打印结构体指针数组函数
void printStudents(Student *stu, int count);
void printStudents(Student *stu, int count)
{
for (int i = 0; i < count; i++) {
printf("num = %d, name = %s, gender = %c, score = %.2f\n", (stu+i)->num, (stu+i)->name, (stu+i)->gender, (stu+i)->score);
}
}
// 修改结构体变量的成员变量的值
void changeScore(Student *stu, int count);
void changeScore(Student *stu, int count)
{
for (int i = 0; i < count; i++) {
if ((stu + i)->gender == 'm') {
(stu + i)->score += 10;
(stu + i)->score = (stu + i)->score > 100 ? 100 : (stu + i)->score;
}
}
}
// 结构体指针
void func1();
void func1()
{
// 创建结构体类型
Student stu1 = {1, "xiaowang", 'm', 89.5};
// 使用结构体指针指向stu1
Student *stu = &stu1;
// 指针的大小只与操作系统有关
printf("%lu\n", sizeof(stu));
// 使用指针变量修改结构体成员变量的值
strcpy(stu->name, "wangwang");
stu->num++;
// 使用结构体指针访问成员变量
printf("num = %d name = %s gender = %c score = %.2f\n", (*stu).num, (*stu).name, (*stu).gender, (*stu).score);
printf("num = %d name = %s gender = %c score = %.2f\n", stu->num, stu->name, stu->gender, stu->score);
// (*p)对指针取值后的结果是结构体变量,‘.num’是访问成员变量,使用指针可以直接访问结构体变量'stu->num'
// 指针的地址,是结构体首个成员变量的地址
printf("stu point = %p\n", stu);
printf("stu1.num point = %p\n", &stu1.name);
// 使用指针修改成员变量的值
(*stu).num = 2;
printf("%d", stu->num);
}
// 练习1
void practice1();
void practice1()
{
// 1. 定义一个点坐标的结构体CPoint,包含两个float 成员x,y。
typedef struct {
float x;
float y;
} CPoint;
// 2. 定义两个CPoint结构体变量m,n
CPoint m = {2, 5};
CPoint n = {4, 10};
// 3. 使用两个结构体指针分别指向m,n
CPoint *x = &m;
CPoint *y = &n;
// 4. 然后通过指针计算两点距离(提示:1、勾股定理,2、开方函数sqrt)
double space = sqrt((x->x - y->x) * (x->x - y->x) + (x->y - y->y) * (x->y - y->y));
printf("space = %.2f\n", space);
}
// 练习2
void practice2();
void practice2()
{
// student stu = {1,”lan ou”,’m’,95.6};
// student * p = &stu;
// 请通过p将name成员中的第一个字母改成大写,所有’ ‘(空格)改成下划线’_’
// 定义结构体变量
Student stu2 = {1, "lan ou", 'm', 98.0};
// 使用指针指向结构体变量
Student *p = &stu2;
// 使用字符指针指向结构体的成员变量
char *s = p->name;
// 循环判断并打印结果
while (*s != '\0') {
// 判断是否是空格
if (*s == ' ') {
*s = '_';
}
// 打印字符
printf("%c", *s);
// 指针向下移动1个单位
s++;
}
}
// 结构体指针数组
void func2();
void func2()
{
// 结构体数组的数组名是一个结构体指针常量
Student stu3 = {1, "xiaoming", 'm', 45.6};
// 结构体数组与指针
Student stus[] = {
{1, "xiaoyi", 'f', 45.6},
{2, "xiaoer", 'f', 15.6},
{3, "xiaosan", 'm', 105.6}
};
Student *p2 = stus; // p为结构体指针变量,stus为数组名
printf("%p\n", p2);
printf("%p\n", p2 + 1);
printf("%p\n", p2 + 2);
printf("%lu\n", sizeof(stus[0]));
// 同下面的情况一样
int array[3] = {0};
int *p1 = array;
// 根据指针取出结构体数组中的结构体变量中的成员变量
printf("%s\n", (p2 + 2)->name);
// 调用函数,打印结构体数组中的所有元素
printStudents(stus, sizeof(stus) / sizeof(Student));
// 练习3
// 使用指针查找学员数组中性别为男的学员,成绩增加10分,超过100分的记为100分)
changeScore(stus, sizeof(stus) / sizeof(Student));
printStudents(stus, sizeof(stus) / sizeof(Student));
// 使用指针查找数组中的元素
Student stus2[] = {
{1, "lan ou", 'm', 98.0},
{1, "haha", 'm', 3.3},
{1, "haha", 'm', 3.3}
};
printf("%lu\n",sizeof(stus2));
Student *p3 = stus2;
printf("%p\n", p3);
printf("%p\n", stus2 + 1);
printf("%p\n", p3 + 2);
}
int main(int argc, const char * argv[])
{
// 预编译指令的使用,所有的预编译指针都是以‘#’号开头
// 不带参数的宏,非常简单,纯字符串的替换
#define PI 3.1415926
// 使用不带参数的宏
printf("result = %.2f\n", PI * 3 * 3);
// 带参数的宏,在使用带参数的宏的时候,需要把每一个参数都带上一个小括号,防止因为运算符优先级的问题导致程序出错
#define kSum(A, B) ((A) + (B))
// 使用带参数的宏
int a = 10, b = 20;
int sum = kSum(a, b);
printf("sum = %d\n", sum);
// 宏的命名规则
// 1. 全部使用大写字母,例如:SUM、MAXVALUE、DIFF
// 2. 使用‘k’加驼峰命名法,例如:kSum、kMaxValue、kDiff
// 条件编译
// 如果定义了这个宏
#ifdef PI
printf("已经定义了PI\n");
#else
printf("没有定义PI\n");
#endif
// 如果没有定义这个宏
#ifndef PI
printf("没有定义PI\n");
#else
printf("已经定义了PI\n");
#endif
#define kAbc 10
// 判断一个宏表达式
#if kAbc == 10
printf("定义了kAbc");
#else
printf("没有定义abc");
#endif
return 0;
}