一:结构体指针
指向结构体变量的指针,称为结构体指针
Stu stu1={0};
Stu *p=&stu1;
这里Stu*:表示结构体指针类型(类型)
p:表示结构体指针变量(变量名)
&stu1:表示结构体变量地址(初值)
结构体指针直接访问成员变量:有以下两种方式,第二种更加常用
(1)(*p).sex='m';
(2)p->sex='m'
课上练习一:定义⼀一个点坐标的结构体CPoint,包含两个float成员x,y。定义两个CPoint结构体变量m,n使⽤用两个结构体指针分别指向m,n然后通过指针计算两点距离(提⽰示:1、勾股定理,2、开⽅方函数sqrt)
typedef struct point
{
float x;
float y;
}CPoint;
CPoint m={3,5};
CPoint n={6,9};
CPoint *p_m=&m;
CPoint *p_n=&n;
//访问方法一:指针变量名->成员变量
double result1=sqrt((p_m->x-p_n->x)*(p_m->x-p_n->x)+(p_m->y-p_n->y)*(p_m->y-p_n->y));
printf("两点的距离是:%lf\n",result1);
//访问方法二:(*指针变量名).成员变量(最好不用)
double result2=sqrt(((*p_m).x-(*p_n).x)*((*p_m).x-(*p_n).x)+((*p_m).y-(*p_n).y)*((*p_m).y-(*p_n).y));
printf("两点的距离是:%lf\n",result2);
课上练习二:
typedef struct stu
{
int num;
char name[20];
char sex;
float score;
}student;
student stu={1,"lan ou",'m',95.6};
//定义结构体指针:
student *p=&stu;
p->.name[0]='L';
printf("%s\n",p->.name);
int i=0;
while(p->.name[i]!=0){
if(p->.name[i]==' '){
p->.name[i]=='_';
i++;
}
}
printf("%s\n",p->.name);
二:结构体数组与指针的关系
顾名思义,也就是说该指针是指向于数组(只是多个结构体组成的数组)的指针,不同于上面的是指向于结构体的指针。
如下例子:
定义一个结构体
typedef struct stu
{
int num;
char name[20];
}Stu;
Stu stu1={1,"zhangsan"};
Stu stu2={2,"wukong"};
Stu stu3={2,"bajie"};
Stu stus[3]={stu1,stu2,stu3};
Stu *p=stus;这就是一个结构体数组指针//stus本来就是一个数组名。也就是数组的首地址stus[0]地址
//访问数组的变量则可以“(p+i)->数组变量名”的格式访问
for (int i=0; i<3; i++) {
printf("%s\n",(p+i)->name);//(p+i)则相当于数组stus[i],跟上面的结构体指针不同,不会有(p+i)这回事
}
//把原来数组的第二个(p+1)学生的学号num修改成4号,要用指针p,也可以用数组stus[1].num=8
(p+1)->num=4;
// stus[1].num=8;
//访问结构体数组则可以用指针(p+1)->name,也可以用数组stus[1].num
printf("num=%d,name=%s\n",stus[1].num,(p+1)->name);
//知识点3
//结构体指针为函数参数(传的是指针,则返回的也是指针)
//使⽤用指针查找学员数组中性别为男的学员,成绩增加10分,超过100分的记为100分)
// student stu1={1,"lanou",'m',95.6};
// student stu2={2,"dagang",'m',65.6};
// student stu3={3,"lihong",'f',85.6};
// student stus[3]={stu1,stu2,stu3};
// student *p=stus;
// //打印指针数组,调用打印函数
// print(p,4);
// //调用改变函数
// gaibian(p,4);
// //打印指针数组,调用打印函数
// print(p,4);
// for (int i=0; i<3; i++) {
// printf("num=%d,name=%s,sex=%s,score=%f\n",(p+i)->num,(p+i)->name,(p+i)->sex,(p+i)->score);
// }
// student *p_stu=&stu;
函数定义:
传的是指针,则返回的也是指针
student * gaibian(student *p,int count){//定义一个指针数组函数student * gaibian()
for (int i=0; i<count; i++) {
if ((p+i)->sex =='m') {
if (((p+i)->score +=10)>=90) {
strcat((p+i)->name, "高富帅");
}else{
strcat((p+i)->name, "穷光蛋");
}
}else{
printf("女生不用修改\n");
}
if ((p+i)->sex =='m') {
if ((p+i)->score >=100) {
(p+i)->score=100;
}
}
}
return p;//不可遗漏,返回的也是指针数组
}
student * print(student *p,int count)
{
for (int i=0; i<count; i++) {
printf("num=%d,name=%s,sex=%c,score=%f\n",(p+i)->num,(p+i)->name,(p+i)->sex,(p+i)->score);
}
return p;
}
三:预编译指令
在头文件里写的文件:
//预编译知识点4
//main函数里面的内容:
//预编译知识点4,
//(1)头文件
//(2)#define N 30表示把N定义为30,还可以替换表达式或函数,但一般不用,只用来替换常量变量值,书写要么是纯大写,或者驼峰命名法,如果有表达式则每一个都要加上括号(),如((A)+(B))
#define PI 3.1415926
//带参宏
#define COUNT(A,B) ((A)>(B)?(A):(B))//找两个数的大值
//(3)条件编译(后面不跟任何东西)
#define KIOS //(1)头文件
//(2)#define N 30表示把N定义为30,还可以替换表达式或函数,但一般不用,只用来替换常量变量值,书写要么是纯大写,或者驼峰命名法,如果有表达式则每一个都要加上括号(),如((A)+(B))
//(3)条件编译
//如:
float r=5;
float result=2*PI*r;
printf("%f\n",result);
int max=COUNT(3+5,2+8);
printf("%d\n",max);
//(3)条件编译可以放在main函数里面
//用于IOS跨平台开发时用
//1)形式一:
#ifdef KIOS//KIOS跟上面的KIOS一样则输出第一句,否则输出else那句
printf("KIOS已经被定义过\n");
#else
printf("KIOS未被被定义过\n");
#endif
//2)形式二:
#ifndef KIOS
printf("KIOS未被定义过\n");
#else
printf("KIOS已经被定义过\n");
#endif
//3)形式三:
#if 3
printf("if为真,即非零,输出这句");
#else
printf("if的条件为假0,则输出这句");
#endif