指向指针的指针
一维数组变量,比如int arr[],arr相当于是 int* 类型。
二维数组变量,比如int arr[][],arr相当于 int ** 类型,指向指针的指针。
*(arr+i)与arr[i]相当于一维数组,因此相当于int*类型。
总结:&会导致在指定类型的后面加一个星号。
int a = 5; &a是int*类型, &(&a)相当于int**类型。
*会导致在指定类型的后面减一个星号。
int * p; *p是int类型
int ** p; *p是int*类型
main函数
main函数 C程序的入口:
int main(int argc , char* argv[])
- main:是函数的名字。
- char* argv[],此时就相当于char** argv:可用于获取用户运行该程序时所输入的参数。
- int argc:记录argv数组的长度。
- int返回值:代表程序的结束状态,一般0代表正常结束;1代表因为错误而结束。
结构体
C的数据类型:
- 基本类型:short\int\long\long long, float、double、char、BOOL、枚举
- 构造类型: 结构体和联合体(用的少)
- 指针类型
结构体可以包含多个成员。比如Point类型,就要包含x、y两个坐标。Rect类型,要包括x、y、width、height成员。
【注意】:结构体就相当于把多个数据打包成一个整体。以后用的时候还是要单独使用结构体的单个成员。
结构体,类似于前面介绍的枚举,需要先定义类型,再定义变量。
分开定义结构体类型和结构体变量
定义结构体类型:
struct 结构体类型名{
成员类型 成员名1;
成员类型 成员名2;
...
}
定义结构体变量:
struct 结构体类型名 变量 ; 使用结构体类型来定义变量
结构体类型和结构体变量同时定义:
struct {
成员类型 成员名1;
成员类型 成员名2;
} 变量1, 变量2, 变量3……;
typedef: 给已有的类型起个别名。
typedef 已有类型 新名字;
使用typedef为结构体指定别名,有两种方式:
第一种方式
struct 结构体类型 {
// 成员定义
}
typedef struct 结构体类型 类型别名
第二种方式
typedef struct 结构体类型 {
// 成员定义
} 类型别名
实际上,OC提供了大量的结构体类型:CGPoint、CGRect、CGSize……NSRange
比如CGPoint类型,OC的定义代码如下:
struct CGPoint {
CGFloat x;
CGFloat y;
}
typedef struct CGPoint CGPoint
结构体变量的初始化和使用
结构体变量可以赋初始值,用{成员1,成员2,成员3,...}的形式即可对结构体变量赋初始值。
{成员1,成员2,成员3,...}只能在定义结构体变量时、赋初始值时使用,其他地方不能使用。
结构体的使用:
结构体变量.成员名 —— 通过这种方式,即可对指定成员赋值,也可获取指定成员的值。
关于结构体变量的赋值:
1. 花括号语法可同时对所有结构体变量的所有成员赋值,但只能在定义结构体变量时赋初始值。
2. 程序可用类型相同的一个结构体对另一个结构体赋值。
3. 可以对结构体的每个成员分开赋值。
通常技巧是,程序会考虑为结构体提供一个MakeXxx的函数
Apple几乎所有的结构体,都有一个对应的MakeXxx函数或XxxMake函数。
结构体数组
结构体指针
程序通过结构体指针来访问结构变量的成员时,可用如下语法:
结构体指针 -> 成员
块(代码块、block)
块是Object-C对C所做的扩展,因此只要是在Object-C编程中非常实用。
一句话:块,相当于一个【匿名】的函数。
定义块的语法:
^ [返回值类型] (形参列表) {
// 执行体
}
[返回值类型] 函数名(形参列表) {
// 执行体
}
其实,块,就是相当于定义函数时把函数名去掉,并在最开始加个 ^ 符号。
关于块的语法:
1. 必须以^开头
2. 返回值类型可以省略。但省略返回值类型之后,并不代表返回值类型为int。
3. 块没有名字。
4. 如果块没有参数,可以留空,但通常会用void作为占位符。
下面就是一个块:
^(void) {
}
定义块类型的变量
块返回值类型 (^块变量名)(形参列表)
这个语法, 跟定义 函数指针的语法非常相似:
定义函数指针变量的语法为:
函数返回值类型 (*指针变量名)()
备注: 块本身就是用于取代函数指针的,而且块用起来更加方便,更加强大。
块的真实使用场景 —— 在Cocoa Touch开发中大量使用块。
有些函数、有些方法需要传入一个块参数。
(1) 使用typedef定义一个块类型。
typedef 块返回值类型 (^块变量类型)(形参列表);
定义快类型的语法和定义块变量的语法几乎相同,只是定义块类型时需要在前面添加typedef关键字。
定义了块类型之后:主要就是方便以后复用这个块类型。
- 程序可用这个块类型来定义变量。
- 程序也可使用这个块类型来声明函数的形参。
(2) 也可以直接在定义函数、方法时声明块类型的形参:只要在形参列表中定义一个或多个块类型的参数即可。
在Cocoa Touch开发中,很多方法都需要传入一个代码块参数 —— 通常会把代码块参数作为最后一个。
在极端的情况下,Cocoa Touch的有些函数、方法甚至需要传入多个代码块参数。
块与局部变量
代码块,会捕获(capture)局部变量的值。
1. 程序在定义代码块时,如果访问了局部变量,代码块会【立即】得到局部变量的【副本】。
2. 编译器不允许在代码块中修改被捕获的局部变量的值。
如果你希望代码块不去捕获局部变量的值,则需要__block修饰该局部变量。