黑马程序员——C语言基础---结构体、枚举

——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);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值