——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
第一讲 结构体的概念和定义
我们可以将描述某个事物的一组变量定义为结构体。和数组类似,结构体也是集合变量,不同的是,结构体可以定义不同类型的变量。例如,我们可以定义一个人结构体Person ,该结构体变量中可以定义int 类型的年龄、字符串类型的姓名和布尔类型的婚否等。
结构体的语法结构如下:
struct 结构体名称{
变量列表;
};
下面代码定义了一个点结构体Point和一个矩形结构体Rect ,矩形结构体 Rect 嵌套点结构体Point,并声明点结构体Point和矩形结构体Rect ,为其赋值,并输出结果。
结构体作用:
结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成你想要的数据类型。以方便日后的使用。
在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型。由于C语言内部程序比较简单,研发人员通常使用结构体创造新的“属性”,其目的是简化运算。
结构体在函数中的作用不是简便,其最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了。
摘自:百度百科
一、定义结构体
基本语法:
struct 结构体名字 {
类型 名字;
类型 名字;
类型 名字;
…
};
结构体的定义方法三种,请继续往下看。
定义方法一:
struct programmer {
char *name;
int age;
int phone;
};
初始化:
struct programmer proTest = {“Garvey”, 28, “13823992034”};
定义方法二:
struct {
int age;
int tag;
} str1;
初始化,这个只能使用点语法,具体请往下看。
定义方法三:
typedef struct {
char *name;
int tag;
} structExt;
使用typedef可以创建新类型,现在可以使用structExt定义新的结构体变量了。
我们可以看到,方法一和方法二的区别。方法一声明了结构体名字,但没有声明结构体变量。方法二声明了结构体变量,但没有声明结构体名字。因此我们可以知道:“结构体名字和结构体变量必须有其一,也可以两者都存在”。
结构体名字及结构体变量都存在,例:
struct programmer {
char *name;
int age;
char *phone;
} proSuccess, proFail;
//
// main.m
// Foundation_结构体
//
// Created by Unisk on 13-9-14.
// Copyright (c) 2013年 Test. All rights reserved.
//
#import <Foundation/Foundation.h>
void test(){
struct Date {
int year;
int month;
int day;
};
struct Date d={2013,9,14};
d.day=10;
}
void test1(){
typedef struct Date {
int year;
int month;
int day;
} Mydate;
// Mydate d={2013,9,15};
}
#pragma 以location开始,length结尾的对象
void range(){
NSRange range=NSMakeRange(9, 22);
NSString *str=NSStringFromRange(range);
NSLog(@"%@ ",str);
}
#pragma 坐标x,y,用于声明一个点
void point(){
NSPoint point;
// point=NSMakePoint(11, 12);
point=CGPointMake(44, 44);
NSString *str=NSStringFromPoint(point);
NSLog(@"%@ ",str);
}
#pragma 宽,高
void size(){
NSSize size=NSMakeSize(11.0, 12.0);
// NSSize size1=CGSizeMake(21.7, 22.3);
NSString *str=NSStringFromSize(size);
NSLog(@"%@",str);
}
#pragma 包含了NSSize和NSPoint
void rect(){
NSRect rect;
// rect.origin.x=10.1;
// rect.origin.y=10.1;
// rect.size.width=100;
// rect.size.height=100;
rect=NSMakeRect(11, 11, 110, 110);
// rect=CGRectMake(11, 11, 80, 80);
NSString *str=NSStringFromRect(rect);
NSLog(@"%@",str);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
// range();
// point();
// size();
rect();
}
return 0;
}
结构体成员访问和赋值
访问和赋值都是使用点语法
访问:
proSuccess.name;
proSuccess.age;
proSuccess.phone;
赋值/修改:
proSuccess.name = “Calvin”;
proSuccess.age = 27;
proSuccess.phone = “13138940202”;
三、注意点
错误初始化写法,这句话在预编译时就会报错:
proSuccess = {“name”, 10, “13732423452”};
写了这么多,都还没输出过任何内容,这里要说的是。使用char定义的变量,输出时要使用%s。例:
NSLog(@”%s- %d - %s”, proTest.name, proTest.age, proTest.phone);
PS:使用char定义的变量,不能存储中文(因为我不知道如何输出,输出会变成码,你根本都看不懂)。
第二讲 结构体嵌套和结构体数组
一、结构体嵌套
1、结构体的成员仍然可以是结构体
2、typedef struct date{
int year;
int month;
int day;
}MyDate;
3、先定义一个日期结构体,此结构体会成为另一结构体的成员
4、struct stu{
int num;
char name[20];
char sex;
MyDate birthday;
float score;
}
5、结构体的成员仍然是结构体
二、成员的访问
1、如果成员本身是结构体,必须找到最低级成员才能使用
2、例如:boy1.birthday.year
三、结构体数组
1、可以将多个结构体变量放到数组中,构成结构体数组
2、例如:
struct stu students[10]={0}
3、通过下标可以访问每个结构体变量
第三讲 各种结构体介绍
Foundation框架中常用的结构体:NSRange、NSPoint\CGPoint、NSSize\CGSize、NSRect\CGRect
// 定义结构体
struct Date {
int year;
int month;
int day;
};
// 依次按照结构体顺序为结构体赋值
struct Date date = {2014,3,20};
// 不按结构体顺序为结构体赋值
struct Date date2 = {.year=2014, .day=20, .month=3};
//NSRange结构体:用来描述范围
typedef struct _NSRange {
NSUInteger location; // 起始位置
NSUInteger length; // 长度
} NSRange;<br><br>// NSUInteger 类型为无符号类型,可以简单理解为表示正整数的类型,在NSLog输出时用ld
//NSRange的简单说明和用法
// 比如想查看字符串"I like oc"中的like在整个字符串中的范围,有三种实现方式:
// 字符串总的起始位置为0空格也要计算,那么love的起始位置为2,当然love的长度为4
// 下面两种实现都是使用为NSRange结构体赋值的方式来实现
NSRange r1 = {2,4}; // 不推荐使用
NSRange r2 = {.location = 2, .length = 4}; // 不推荐使用
// 第三种实现方式是调用NSMakeRange()函数来实现
NSRange r3 = NSMakeRange(2, 4); // 推荐使用<br>
//查找NSString类对象中某些字符在整个类对象中的NSRange
NSString *str = @"I like oc";<br><br>// NSString类的分类已经对这种需求做了实现 因此可以直接调用类方法来实现
NSRange range = [str rangeOfString:@"like"];<br><br>// 打印的NSRange结构体中的变量由于都是NSUInteger类型 因此在输出时用ld
NSLog(@"location = %ld, length = %ld",range.location,rang.length);
//注意:如果没有找到要查找的值NSRange中的length = 0, location = NSNotFound,其中NSNotFound如果以NSLog(@"%d",NSNotFound); 输出一长串 数字;而如果以 NSLog(@"%d",NSNotFound); 输出的就是 -1
NSPoint结构体:通过一个点坐标来标识元素位置
官方定义的NSPoint
// 设置 double 类型的别名为 CGFLOAT_TYPE
# define CGFLOAT_TYPE double
// 定义CGFloat类型为double类型
typedef CGFLOAT_TYPE CGFloat;
// 定义CGPoint结构体
struct CGPoint {
CGFloat x;
CGFloat y;
};
// 定义CGPoint结构体为CGPoint类型
typedef struct CGPoint CGPoint;
// 设置结构体CGPoint = NSPoint
typedef CGPoint NSPoint;<br><br>总结:可以看出CGPoint = NSPoint 本质都是结构体,里面包含了两个double类型来描述一个点
NSPoint的一般用法
// 同一个点的两种表现方式
2.
CGPoint point = NSMakePoint(20, 20); // 不常用
3.
NSPoint point2 = CGPointMake(20, 20); // 常用<br><br> // CGPointZero == CGPointMake(0,0);<br>
NSSize结构体:描述元素的尺寸(宽和高),定义和NSPoint类似不再赘述,一般用法为:
CGSize size = NSMakeSize(20, 40);
2.
NSSize size2 = CGSizeMake(40, 20); // 常用
CGRect结构体:用于描述元素的位置(CGPoint)和尺寸(CGSize),因此可以说CGRect是描述了一个在手机屏幕上的矩形
官方定义的CGRect
struct CGRect {
2.
CGPoint origin; // 描述元素位置坐标
3.
CGSize size; // 描述元素尺寸
4.
};<br>
5.
typedef struct CGRect CGRect;
一般用法
// 描述一个坐标位置为(20,20)宽高分别为50和100的元素
2.
CGRect rect = CGRectMake(20, 20, 50, 100); // 常用
3.
NSRect rect2 = NSMakeRect(20, 20, 50, 100);
其他用法
CGRectZero == CGRectMake(0,0,0,0);<br> CGSizeZero == CGSizeMake(0,0);<br> CGPointZero == CGPointMake(0,0);<br><br> // 第一种写法:坐标为(20,20)宽高分别为50和100
02.
CGRect rect = {{20,50},{50,100}};
03.
04.
// 第二种写法:坐标为(20,20)宽高分别为50和100
05.
NSPoint point = CGPointMake(20, 20);
06.
NSSize size = CGSizeMake(50, 100);
07.
CGRect rect2 = {point,size};
08.
09.
// 第三种写法:坐标为(0,0)宽高分别为50和100
10.
CGRect rect3 = {CGPointZero,CGSizeMake(50, 100)};<br><br>
模拟函数CGRectMake的实现过程
// 模拟CGRectMake方法的实现
02.
CGRect CGRectMake2(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
03.
{
04.
// 定义一个CGRect类型的结构体rect
05.
CGRect rect;
06.
07.
// 为结构体内部坐标x/y赋值
08.
rect.origin.x = x;
09.
rect.origin.y = y;
10.
11.
// 为结构体内部迟钝坐标width/height赋值
12.
rect.size.width = width;
13.
rect.size.height = height;
14.
15.
return rect;
16.
}<br><br>// 依照这一逻辑:CGPointMake函数、CGSizeMake函数都可以模拟实现
如何快速查看结构体中的值
第一种方式:从结构体中将值依次取出来
NSRect rect = CGRectMake(20, 20, 50, 100);<br>
2.
NSLog(@"x = %f, y = %f, width = %f, height = %f",rect.origin.x, rect.origin.y
3.
, rect.size.width, rect.size.height); // 这里的. 不是get方法只是单纯的从结构体中获取值而已
第二种方式:将结构体直接转换为字符串后打印
NSRect rect = CGRectMake(20, 20, 50, 100);
2.
3.
// 先将结构体转换称为字符串
4.
NSString *strRect = NSStringFromRect(rect);
5.
6.
// 直接打印转换后的字符串
7.
NSLog(@"%@",strRect);<br><br> // NSSize/NSPoint这两种结构体NSStirng也提供了类似的方法
.结构体比较常用的函数
结构体常用函数是在CoreGraphics.framework框架下面,因此需要先添加框架
较常用的方法
// 1.判断两个点的位置是否相等
02.
BOOL pointIsEqual = CGPointEqualToPoint(CGPointMake(50, 100), CGPointMake(100, 50));
03.
NSLog(@"%d",pointIsEqual);
04.
05.
// 2.判断尺寸大小是否相等
06.
BOOL sizeIsEqual = CGSizeEqualToSize(CGSizeMake(50, 100), CGSizeMake(50, 100));
07.
NSLog(@"%d",sizeIsEqual);
08.
09.
10.
// 第一种写法:坐标为(20,20)宽高分别为50和100
11.
CGRect rect1 = {{20,50},{50,100}};
12.
// 第二种写法:坐标为(20,20)宽高分别为50和100
13.
NSPoint point = CGPointMake(20, 20);
14.
NSSize size = CGSizeMake(50, 100);
15.
CGRect rect2 = {point,size};
16.
17.
18.
// 3.判断两个矩形是否相等
19.
BOOL rectIsEqual = CGRectEqualToRect(rect1, rect2);
20.
NSLog(@"%d",rectIsEqual);
21.
22.
23.
// 4.判断一个点是否在矩形上面
24.
BOOL isContent = CGRectContainsPoint(rect1, CGPointMake(20, 50));
25.
NSLog(@"%d",isContent);