指向结构体变量的指针,称为结构体指针。
typedef struct student Stu;
Stu stu1 = {0};
Stu * p = &stu1;
Stu *结构体指针类型(类型), p 结构体指针变量(变量名); &stu1结构体变量地址(初值).
结构体指针访问成员
(*p).sex ='m'; p ->sex = 'm';
(*p)对指针取值后是结构体变量, .sex访问的是成员变量.
使用指针可以直接访问结构体的成员变量. p->sex.
指针p是第一个成员变量的首地址.
1.练习题:
定义一个点坐标的结构体CPoint,包含两个float 成员x,y。
使⽤两个结构体指针分别指向m,n 然后通过指针计算两点距离(提示:1、勾股定理,2、开方函数sqrt)
struct cpoint {
int x;
int y;
};
typedef struct cpoint CPoint;
/ CPoint m ={3, 5};
<span style="font-size:18px;"> // CPoint n = {7, 9};
// // 使用两个结构体指针指向m ,n
// CPoint *p1 = &m;
// CPoint *p2 = &n;
// // 然后通过指针计算两点距离
// int result = (int)sqrt((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y));
// printf("%d\n",result);</span>
2.练习二.
student stu = {1,”lan ou”,’m’,95.6};
student * p = &stu;
请通过p将name成员中的第一个字母改成大写,所有’ ‘(空格)改成下 划线’_’
二.结构体数组和指针的关系
结构体数组的数组名是一个结构体指针常量。
Stu stus[3] = {0};
Stu *p = stus;
P为结构体指针变量,stus为数组名.
相同于: int array[3] = {0}; int *p = array;
(p + i) ->num;
使用指针访问下标为i的元素的成员变量num.
结构体指针为函数参数
void printstudent(Stu *pstu int count)
函数操作结构体数组时需要输入首元素地址和元素个数.
3.练习
使⽤指针查找学员数组中性别为男的学员,成绩增加10分,超过100分 的记为100分)
三 预编译指令
1.宏定义
预编译时进⾏替换(编译前)
宏名命名规则:
纯大写 或者
k+驼峰法
例如 MAX 或者 kMax
宏不是变量
2.普通宏
# define pI 3.1415926
#define 代表宏定义指令 PI 宏名 3.1415926是预编译时被替换的内容.
带参数的宏
#define MUL(A,B) ((A)*(B)) 加 ()为了防止受操作符优先级的影响
条件编译:
作⽤:按不同的条件,编译不同的代码。条件编译 有三种形式
第一种:
#ifdef 标识符
代码段1
#else
代码段2
#endif!
第一种形式
如果 标识符 被#define过 ,编译器编译代码段1,否则编译代码段2。
第二种:
#ifndef 标识符
代码段1
#else
代码段2
#endif
第⼆种形式
如果 标识符 未被#define过 编译器编译代码段1,否则编译代码段2。
第三种:
#if 常量表达式
代码段1
#else
代码段2
#endif
第三种形式
如果常量表达式结果非0 编译器编译代码段1,否则编译代码段2。
总结:
一、结构体指针(如何访问成员?)
二、结构体数组与指针(如何访问某个元素的成员?)
三、条件编译(如何进行条件编译?)
******************************************************************
main.m
#import <Foundation/Foundation.h>
#import "Test.h"
#define PI 3.14
#define AREA(r) PI * r * r
#define AVG(a,b) (a + b)/2.0
int main(int argc, const char * argv[])
{
//1. (**)写一个函数交换两个结构体变量
// Cup cup1 = {"lekou",500};
// Cup cup2 = {"qinhe",1000};
// Cup *p = &cup1;
// Cup *q = &cup2;
// exchangeStruct(p ,q);
// printf("%s %d\n",p -> name,p -> Volume);
// printf("%s %d ",q -> name,q -> Volume);
//2. (**)有一学生数组写一函数打印出指定分数段的学生信息
// Student stus[6] = {
// {"zan",'f',18,90},
// {"zangzang",'f',19,92},
// {"xiao",'f',20,96},
// {"zheliang",'m',20,76},
// {"xiaoheihei",'m',20,76},
// {"xiaoheige",'m',20,96},
// };
// Student *a = stus;
// printfStudentByScore(a, 6, 70, 89);
//3. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按学号 从小到大),使用结构体指针操作数组元素
// Students stus[5] = {
// {"zan",18,90},
// {"zhangzang",19,92},
// {"xiaozangzang",20,96},
// {"zhengliang",16,96},
// {"xiaoheihei",17,86},
// };
// Students *p = stus;
// sortStudentByNumber(p, 5);
//4. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按姓名 从小到大),使用结构体指针操作数组元素
// Students stus[5] = {
// {"zan",18,90},
// {"zang",19,92},
// {"xiao",20,96},
// {"zheliang",16,96},
// {"xiaoheihei",17,86},
// };
// Students *p = stus;
// sortStudentByName(p, 5);
//5. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按分数 从小到大),使用结构体指针操作数组元素
// Students stus[5] = {
// {"zan",18,90},
// {"zang",19,92},
// {"xiao",20,96},
// {"zheliang",16,96},
// {"xiaoheihei",17,86},
// };
// Students *p = stus;
// sortStudentByScore(p, 5);
//6. (**)定义一个求圆面积的宏
printf("面积为:%.2f",AREA(2));
//7. (**)定义一个求2个数平均数的宏
printf("平均数:%.1f",AVG(3,2));
.h文件声明
//1. (**)写一个函数交换两个结构体变量
typedef struct cup{
char name[20];
int Volume ;
}Cup;
void exchangeStruct(Cup *c1,Cup *c2);
//2. (**)有一学生数组写一函数打印出指定分数段的学生信息
typedef struct student{
char name[20];
char sex;
int age;
float score;
}Student;
void printfStudentByScore(Student *s,int count,float score1,float score2);
//3. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按学号 从小到大),使用结构体指针操作数组元素
typedef struct students{
char name[20];
int number ;
float score;
}Students;
void sortStudentByNumber(Students *s,int count);
//4. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按姓名 从小到大),使用结构体指针操作数组元素
void sortStudentByName(Students *s ,int count);
//5. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按分数 从小到大),使用结构体指针操作数组元素
void sortStudentByScore(Students *s ,int count);
.m文件进行实现
/1. (**)写一个函数交换两个结构体变量
void exchangeStruct(Cup *c1,Cup *c2){
//注意传址,不能传值!
Cup temp = *c1;
*c1 = *c2;
*c2 = temp;
}
//2. (**)有一学生数组写一函数打印出指定分数段的学生信息
void printfStudentByScore(Student *s,int count,float score1,float score2)
{
for (int i = 0; i < count; i ++) {
//条件是 分数在给出的 两个分数之间
if (s[i].score >= score1 && s[i].score <= score2) {
printf("%s %c %d %f \n",s[i].name,s[i].sex,s[i].age,s[i].score);
}
}
}
//3. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按学号 从小到大),使用结构体指针操作数组元素
void sortStudentByNumber(Students *s,int count)
{
for (int i = 0; i < count - 1 ; i ++) { //冒泡排序,注意:换位的条件是学号大小,传的是址
for (int j = 0; j < count - 1 - i; j ++) {
if (s[j].number > s[j + 1].number) {
Students temp ;
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < count; i ++) {
printf("%s %d %f\n",s[i].name,(s + i) ->number,s[i].score);
}
}
//4. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按姓名 从小到大),使用结构体指针操作数组元素
void sortStudentByName(Students *s ,int count){
for (int i = 0; i < count - 1; i ++) {
for (int j = 0; j < count - i - 1; j ++) {
if (strcmp(s[j].name, s[j + 1].name) > 0) {
Students temp;
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < count; i ++) {
printf("%s %d %f\n",s[i].name,(s + i) ->number,s[i].score);
}
}
//5. (**)有一学生数组,包含5个学生,写一个函数,对学生排序(按分数 从小到大),使用结构体指针操作数组元素
void sortStudentByScore(Students *s ,int count){
for (int i = 0; i < count - 1; i ++) {
for (int j = 0; j < count - i - 1; j ++) {
if (s[j].score > s[j + 1].score) {
Students temp;
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < count; i ++) {
printf("%s %d %f\n",s[i].name,(s + i) ->number,s[i].score);
}
}
课堂笔记
main.m
#import <Foundation/Foundation.h>
#import "1112.h"
//宏定义,预编译时进行替换;
// 宏后面不要加括号,大部分接口里用.
#define kImageWidth 200
#define kImageHeight 200
//有参数的宏
#define kMax(A,B) A > B ? A : B
#define kMul(A, B) ((A) * (B))
#define android 1
// 条件编译
// 如果之前定义过宏android
#ifdef android
// 如果定义过,则编译这段代码
#define kWidth 400
#else
// 否则编译else下的代码
#define kWidth 320
//条件编译结束
#endif
// 如果没有定义android
#ifndef android
// 则执行这段代码
#define kHeight 480
#else
#define kHeight 800
#endif
//最常用的
#if iOS7
// 代码1
#define state 20
#else
// 代码2
#define state 0
#endif
int main(int argc, const char * argv[]) {
printf("%d\n",kHeight);
printf("%d\n", kImageWidth);
printf("%d\n",kMul(3,2+3));
int arr[kImageWidth] = {0};
// int arr[8] = {3, 1, 5, 6};
// bubbleSort(arr, 4);
//创建结构体变量
// MYLanguage language1 = {"C", "面向过程", 1};
// MYLanguage language2 = {"Objective-C", "面向对象", 3};
// MYLanguage language3 = {"C++", "全能王", 4};
// MYLanguage language4 = {"Java", "面向对象", 2};
// MYLanguage language5 = {"C#", "微软版Java", 5};
//
// // 定义指针变量(需要注意类型名和初始值)
// MYLanguage *p1 = &language1;
// p1 所占空间大小 : 8个字节
//*p1能取出什么样的数据---> *p1 -----> *&language---> language1
//结构体指针特有的操作方式,需要用别的操作符->
// char *str = (*p1).name;
// char *str1 = (*p1).type;
// int str2 = (*p1).rank;
// printf("%s\n%d\n", str1, str2);
// char *str = p1->type;
// printf("%s\n", str);
// printStruct(&language1);
// 定义⼀一个点坐标的结构体CPoint,包含两个float 成员x,y。 定义两个CPoint结构体变量m,n
// 使⽤用两个结构体指针分别指向m,n 然后通过指针计算两点距离(提⽰示:1、勾股定理,2、开⽅方函数sqrt)
// CPoint m ={3, 5};
// CPoint n = {7, 9};
// // 使用两个结构体指针指向m ,n
// CPoint *p1 = &m;
// CPoint *p2 = &n;
// // 然后通过指针计算两点距离
// int result = (int)sqrt((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y));
// printf("%d\n",result);
// **********************************************************************
//定义结构体数组
// MYLanguage languages[3] = {{"C++", "面向对象", 4},{"C", "面向过程", 1},{"Objective-C", "面向对象", 3}};
// // 定义一个结构体指针用来保存结构体数组的首地址
// MYLanguage *p = languages;
// bubblesort(p, 3);
// printlanguages(p, 3);
//
// //需要用->操作符
// printf("%s\n",(p+1)->type); //p[1].type
// printf("%s\n",(p+2)->name);
// printf("%c\n",p->name[1]);
// printf("%s\n",p->name + 1);
// printf("%d\n",(p+2)->rank);
访问成员 数组[索引]/ 结构体 . / 结构体指针 ->
// printlanguages(languages, 3);
.h文件
//void bubbleSort(int *arr, int count);
struct language {
char name[20];
char type[20];
int rank;
};
typedef struct language MYLanguage;
void printStruct(MYLanguage *l);
struct cpoint {
int x;
int y;
};
typedef struct cpoint CPoint;
void printlanguages(MYLanguage *arr, int count);
void swap(MYLanguage *l1, MYLanguage *l2);
void bubblesort(MYLanguage *arr, int count);
.m文件
//void bubbleSort(int *arr, int count){
// int flag = 1;
// for (int i = 0; i < count - 1 && flag == 1; i++) {
// // 最关键的一行,初始化状态
// flag = 0;
// for (int j = 0; j < count - i - 1; j++) {
// if (arr[j] > arr[j+1]) {
// int temp = arr[j];
// arr[j] = arr[j +1];
// arr[j+1] = temp;
// // 改状态
// flag = 1;
//
// }
// }
// printf("第%d次的冒泡过程\n",i+1);
// }
//}
void printStruct(MYLanguage *l){
// 结构体用.操作符, 结构体指针用->操作符
printf("%15s %20s %d\n",l->name, l->type, l->rank);
}
void printlanguages(MYLanguage *arr, int count){
for (int i = 0; i < count; i++) {
printStruct( arr + i);
}
}
void swap(MYLanguage *l1, MYLanguage *l2){
MYLanguage temp = *l1;
*l1 = *l2;
*l2 =temp;
}
void bubblesort(MYLanguage *arr, int count){
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1 ; j++) {
if (arr[j].rank > arr[j + 1].rank) {
swap(arr + j, arr + j + 1);
}
}
}
}