结构体指针
结构体:
就是一种自定义的类型。
typedef :
给一个已经存在的类型取一个新的名字。
//结构体是一种自定义的类型
//CPoint //typedef 给一个类型取一个新的名字。 typedefstruct CPoint{ float x; float y; }CPoint; //练习 //声明一个student结构体,姓名,年龄,班级 //定义一个stu的变量("王铁柱",18,5) //使用结构体指针,打印成员变量 typedefstruct Student{ char name[20]; int age; int s_class; }Student; |
结构体指针:
就是指向结构体的指针变量。
定义结构体变量:
CPoint c = {1.2,2.3};
定义结构体指针:
CPoint *cp1 = &cp;
用结构体指针取值:
结构体指针取值,先通过地址取到结构体,然后通过结构体,取到成员变量。(*cp1).x
// //取x,y的值 // //先通过地址,取到结构体 // //再通过结构体,取到成员变量 // printf("x = %f\n",(*cp1).x);//打印1.2,(*p1)这个小括号不能丢 // printf("y = %f\n",(*cp1).y);//打印2.3 |
除了上面这种取值方法,还有另外一种方法:用箭头—>
cp1—>x
|
例子:
//练习 //声明一个student结构体,姓名,年龄,班级 //定义一个stu的变量("王铁柱",18,5) //使用结构体指针,打印成员变量 typedefstruct Student{ char name[20]; int age; int s_class; }Student; int main(int argc,constchar * argv[]){ // Student stu = {"王铁柱",18,5}; // Student *sp = &stu; //// printf("姓名:%s",(*sp).name ); //// printf("\n年龄:%d",(*sp).age); //// printf("\n班级:%d",(*sp).s_class); // // //指针可以直接取成员变量的值 -> // printf("姓名:%s\n",sp->name); // printf("年龄:%d\n",sp->age); // printf("班级:%d\n",sp->s_class); return 0; } |
一些练习:
定义一个点结构体,成员变量有俩,x,y都是float型,再main函数定义两个点,求这两点的距离。
#import <Foundation/Foundation.h> typedefstruct CPoint{ float x; float y; }CPoint; int main(int argc,constchar * argv[]) { //练习
// CPoint1 m = {4.5,5.6}; // CPoint1 n = {3.2,8.8}; // // CPoint1 *pm = &m; // CPoint1 *pn = &n; // if (pn->x > pm->x && pn->y > pm->y) { // float length = sqrt((pn->x - pm ->x) * (pn->x - pm ->x) + (pn ->y - pm ->y) * (pn ->y - pm ->y)); // printf("%f\n",length); // return length; // } // if (pn->x < pm->x && pn->y < pm->y) { // float length = sqrt((pm->x - pn ->x) * (pm->x - pn ->x) + (pm ->y - pn ->y) * (pm ->y - pn ->y)); // printf("%f\n",length); // return length; // } // if (pn->x < pm->x && pn->y > pm->y) { // float length = sqrt((pm->x - pn ->x) * (pm->x - pn ->x) + (pn ->y - pm ->y) * (pn ->y - pm ->y)); // printf("%f\n",length); // return length; // } // if (pn->x > pm->x && pn->y < pm->y) { // float length = sqrt((pn->x - pm ->x) * (pn->x - pm ->x) + (pm ->y - pn ->y) * (pm ->y - pn ->y)); // printf("%f\n",length); // return length; // } return 0; }
|
定义一个student结构体,定义一个student变量,把第一个字符改成大写。
#import <Foundation/Foundation.h> typedefstruct Student{ char name[20]; int age; int s_class; }Student; int main(int argc,constchar * argv[]) { //把第一个字符的小写变成大写。 Student stu = {"lan ou",18,5};
Student *sp = &stu; sp->name[0]的意思是:访问了成员变量name,这个name是char型数组,然后取这个数组的第一个值。 sp->name[0] ^ 32的意思是把小写的改成大写,或者将大写的转换成小写。 sp->name[0] = sp->name[0] ^ 32; printf("%s\n",sp->name); return 0; } |
字符的大小写转换:
用到的运算符有:
1、&(按位与):有清0的效果,当一个字符与233用&时,这个字符会转换成大写。
2、|(按位或):有置1的效果,当一个字符与32用 | 时,这个字符会转换成小写。
3、^(异或):一个字符与32用 ^ 时,小写变大写,大写变小写。
// //字符的大小写转换 // // &:清0,与223用 &,全部变成大写 // // |:置1,与32用 | ,全部变成小写 // // char c = 'A'; // printf("%c\n",c^32);//a // printf("%c\n",c | 32);//a // printf("%c\n",c & 223);//A // // char c1 = 'a'; // // printf("%c\n",c1^32);//A,大写变小写,小写变大写 // printf("%c\n",c1 | 32);//a,变成小写 // printf("%c\n",c1 & 223);//A,变成大写
// int arr1[5] = {1,2,3,4,5}; // int *p1 = arr1; // printf("%d\n",*(p1 + 1)); |
结构体数组:
一个数组用来存放结构体,这个数组就是结构体类型的数组。
结构体本身所占的字节,是根据结构体内的成员变量的定义后才确定的。具体的情况,看那个结构体数组那节。
结构体数组指针:
给结构体数组定义指针时,指针直接指向数组的首地址即可。
结构体数组指针本身所占的字节为8个字节,与它所指向的东西无关,只与它所在的操作系统的位数有关。
#import<Foundation/Foundation.h> //Person typedefstruct Person { char name[20]; int age; }Person; int main(int argc,constchar * argv[]) { Person person1 = {"Mike",20}; Person person2 = {"Joe",18}; Person person3 = {"Kitty",17};
//存放结构体的数组,是结构体类型的。 Person arr2[3] = {person1,person2,person3};
// printf("%lu\n",sizeof(Person));//占了24个字节 //结构体指针也是占8个字节 Person *pp =NULL; pp = arr2; //对结构体指针进行+、-的时候,一次性越过的字节数,是根据结构体所占内存来决定的。 // printf("%s\n",pp->name);//Mike // printf("%s\n",(pp+1)->name);//Joe // printf("%s\n",(pp+2)->name);//Kitty return 0; } |
结构体数组取值:
结构体数组取值,有三种方式了:
//存放结构体的数组,是结构体类型的。 Person arr2[3] = {person1,person2,person3}; //结构体指针也是占8个字节 Person *pp =NULL; pp = arr2; // ->这个箭头是给结构体指针用的。 // .这个是给结构体用的。 for (int i = 0; i <3 ; i++) { //结构体数组取值,有三种方式。 printf("%s\n",(pp+i)->name); printf("%s\n",(*(pp+i)).name); printf("%s\n",pp[i].name);
// } |
结构体数组作为函数参数:
当定义一个函数的时候,需要用到结构体数组作为函数参数的时候,再定义函数时,参数里定义一个结构体类型的数组(不用给元素个数),再定义一个int型变量,用来传递这个数组的元素个数。
#import <Foundation/Foundation.h> void persons(Personarr[],int count){ for (int i = 0; i < count ; i ++) { printf("%s\n",arr[i].name); } } int main(int argc,constchar * argv[]) { persons(arr2, 3); return 0; } |
语法糖:参数里的Person arr[],可以写成:Person *arr。
一些练习:
#import <Foundation/Foundation.h> //练习 //使⽤指针查找学员数组中性别为男的学员,成绩增加10分,超过100分的记为100分) //如果要存汉字,一定要用字符数组,char不可以存汉字。 typedefstruct Score { char name[20]; char sex ; float score; }Score;
int main(int argc,constchar * argv[]) { //练习 Score s1 = {"王大催",'f',89.0}; Score s2 = {"李大催",'m',97.0}; Score s3 = {"找打催",'m',81.0};
Score score_arr[3] = {s1,s2,s3}; Score * sp = score_arr; for (int i = 0; i < 3; i ++) { if('m' == (sp + i)->sex ){ (sp + i)->score = (sp + i)->score + 10; if ((sp + i)->score > 100) { (sp + i)->score = 100; } printf("%s是男的,加上10分后的成绩是:%.2f\n",(sp + i)->name,(sp + i)->score); } } return 0; } |
27、预编译指令:
宏定义:
就是在程序编译前,对一些代码进行原封不动地替换。
注意的几点:
(1)、宏定义不是定义变量;
(2)、宏定义,是在编译前对一些代码原封不动地替换;
(3)、宏定义的规范:a、全部字符大写;b、k+驼峰命名法
//宏定义 //宏定义不是定义变量 //原封不动的替换 //明明规范:1.全部大写,2.k +驼峰命名法 #define PI 3.1415926//全部大写
#define kPi 3.1415926//k +驼峰命名法
#define kInt int i = 10//替换语句 int main(int argc,constchar * argv[]) { // 2015-04-07 16:24:27北京 float pi1 =PI; float pi2 =PI; //魔数:如果不给注释,我不知道这个数是啥意思。 float s =PI*5*5;
kInt;//将上面的宏定义的int i= 10;替换掉这个kInt // printf("%d\n",i);//10 return 0; } |
带参宏定义:
#defineMUL(A,B) A*B
注意的一点,在这个宏定义被使用的时候,A和B是原封不动的被替换。例如,我在main函数中,调用这个MUL(A,B),这时候我传的参数是MUL(3,5),此时,是这样替换的:3替换A,5替换B,计算3*5的值。如果此时,我传的参数是:MUL(3+3,5+5),此时替换的情况是这样的:3+3替换A,5+5替换B,计算的情况是3+3*5+5,先计算3*5,然后再计算+和。所以,为了避免出现这样的情况,在宏定义的时候,要对A*B加上括号(),即
#define MUL(A,B) ((A)*(B))
此时计算的情况就是:先3+3,5+5,然后在算乘积。
条件编译:
三种形式:
1、#ifdef
//条件编译 #ifdef PI//如果我宏定义过PI,我就执行int a = 10;如果没有宏定义过 PI,则执行else中的代码 int a = 10;
#else
int a = 20 ;
#endif |
2、ifndef:
#ifndef BB//如果我没有宏定义过BB,我就执行int b = 30;如果宏定义过 BB,则执行else中的代码
int b = 30;
#else
int b = 40;
#endif |
3、#if 常量表达式
//常量表达式 //如果是0,说明是假,执行else //如果是非0,说明是真,执行if //不能使用浮点型 #if 6 >7//(常量表达式)
int c = 50;
#else
int c = 60;
#endif |