Objective-C 程序设计 第十三章

基本的C语言特性

主要讲解了C语言本身的一些特性,以及Objective-C特有的一些处理。相当于进行了复习,并记录了一些盲点,用于复习。

13.1 数组

Fraction *fracts[100];
这是定义了一个包含100个Fraction * 对象的数组。

1. 初始化

int integers[5] = {0,1,2,3,4};
int x = 1234; int a[] = { [9] = x+1; [2] = 3,[1] = 2 } 可以指定位置初始化。
数组a未明确大小,隐式声明为10个元素。

2. 字符数组

如果在字符数组结尾添加一个’\0’,就产生了一个通常称为字符串的变量。可以使用NSLog的%s就可以打印出来(它会持续地显示字符,知道遇到终止符)

3. 多维数组

A[i][j] 就是i行j列的二维数组。
使用双层{}声明一个二维数组时,注意最后一个内部{}后边不要使用逗号。

13.2 函数

函数就是C语言类型的函数。方法是Objective-C的对象拥有的方法。

1. 参数和局部变量

在函数中定义的变量被称为自动局部变量。
静态局部变量用关键字static声明,它们的值在函数调用的过程中保留下来,并且初始化默认为0
局部变量的值只能在定义该变量的函数中访问,不能从函数之外访问。

2. 函数的返回结果

倘若省略函数的返回类型声明,如果有返回值,默认类型为整型。无返回值,默认为void。
如果是方法,则默认为id类型。不建议利用这个默认属性。

void NSLog(NSString *format, …) 使用…来表示数目不定的参数。

只有当前面已经定义或声明了这个函数,编译器才会将参数转换成函数认可的类型。建议:声明所有的函数。把函数声明放倒头文件最好了。

默认函数是外部的,所有与该函数链接在一起的文件中的所有函数或方法都可以调用它。如果是static类型,只有文件内可以使用。(放在函数声明前就可以)

3. 函数、方法和数组

传递数组时,只是传递一个指针。所以对形参数组的修改就是对原始数组的修改。

13.3 块

块是对C语言的一个扩展。
可以给块传递参数,也可以有返回值。
块定义在函数或者方法内部,并能够访问在函数或方法内的块之外的任何变量。
块能够作为参数传递给函数或方法 我想到了闭包呢?不太一样。
语法:
^(void)
{
NSLog(@”Block is here!”);
}
块以插入字符”^”开头为标识的。
将这个块赋值给printMessage
void (^printMessage)(void) =
^(void)
{
NSLog(@”Block is here!”);
};
它的调用方法跟函数一样。
块可以被定义为全局的或者局部的。
块可以访问其范围内定义的变量,变量的值同时作为块定义的值。
不可以在快内部修改已经定义过的变量的值。除非变量声明前加入__block修改器。

13.4 结构

常用语法,定义一个data结构体。
struct data
{
int month;
int day;
int year;
};
声明一个today类型的变量。
struct data today, otherday;
today.day = 21;此处点运算符会自动识别变量为对象还是结构。
打印年份时,需要现实两位数。NSLog中的%.2i格式符号指明了最少显示两位字符,从而强制显示年份开始的0。

1. 结构的初始化

struct date today = {7,2, 2015};
struct date tomorrow = {7}; 其它未指明的未定义。
struct date today = {.month = 7, .day = 2, .year = 2015 };
struct date today = { .year = 2015 };

2. 结构中的结构

经常需要嵌套。
经常使用typedef来简化结构。
typedef struct date sDate; 可以直接使用sDate来声明变量。

3. 关于结构的补充细节

可以直接将变量放在声明后边。
struct date
{
int month;
}, today, tommorw;
还可以直接初始化。
struct date
{
int month;
}, today = { 11, 16, 2015};
以上,两个结构可以理解为struct date today。只不过对date类型进行了声明。

4. 不要忘记面向对象编程思想

使用结构时,考虑是否可以使用对象。

13.5 指针

指针可以高效地表示复杂的数据结构,作为参数传递给函数和方法的值,并且更准确更高效的处理数组。
基础:间接寻址。
取地址符&和间接寻址符*
&: 地址运算符,用来得到变量的指针。
*: 通过地址访问变量。
在指针指向一些值之前,指针的值是没有意义的。

1. 指针和结构

stuct date *datePtr;
datePtr = &today;
(*datePtr).day = 16;
务必使用括号。因为(.)的优先级比(*)要高。
datePtr->day = 16; 结构指针运算符。

2. 指针、方法和函数

指针用作参数和返回值。

3. 指针和数组

Objective-C 编译器将没有下标的数组名称看作是指向输入第一个元素的指针。
valuePtr = valueArr;
valuePtr = &valueArr[0]; 同上
*(valuePtr + i) 访问第i个元素。
valuePtr += i; 向后移动i个元素。
++valuePtr, 向后移动一个元素。
这个1,代表一个单元,或者是指针声明指向的数据元素的大小。
在Objective-C语言中,比较两个指针变量的做法是完全合法的。valuePtr > &valueArr[99], 判断它的指向是否超出了有100个元素的数组的范围,方法是将它与指向数组最后一个元素的指针比较。
可以用来判断谁在前谁在后,比较是否超出了边界等。

1 是数组还是指针
调用函数时,作为参数,实际传递的是数组的指针,而不是数组。这就是为什么可以在函数中修改数组的值。
如果要使用索引来引用数组元素,那么要将对应的形参声明为数组。这能更准确地反映该函数对数组的使用情况。如果要将参数作为指向数组的指针,则要将其声明为指针类型。
2 字符串指针
作为字符串指针,原因是符号表达的便利和高效。最后有一个结束字符\0
3 字符串常量和指针
函数传递字符串作为参数时,实际上传递的是指向该字符串的指针。
这些是C样式字符串,它们不是对象。@”“,这就可以创建一个常量字符串对象。
char *ptr;
ptr = “这是一个字符串”;✅
char text[100];
text = “这是一个字符串”; ❌
但是初始化可以char text[100] = “这是一个字符串”; 这个时候在相应的数组中存储了实际的字符本身以及最后的终止空字符。
char *text = “这是一个字符串”“; 将赋给text一个指向字符串的指针。

4 指针运算

Objective-C中,两指针相减的结果是它们之间所包含的元素个数。
函数指针
编译器不但需要知道指向函数的指针变量,还需要知道函数返回值的类型,以及参数的数目和类型。
int (*fnPtr) (void);
函数调用运算符()比指针间接寻址运算符的优先级高。
允许在函数名称之前添加&标志,但这个不必要。
应用:作为参数传递给其它函数,比如sort函数。
应用:分派表,将函数指针存储在数组中。

5. 指针和内存地址

计算机的内存可以理解为存储单元的顺序集合,计算机内存中的每个单元都有一个相关的编号,称为地址。

13.6. 其它语言特性

1. goto 语句

标签直接放在分之语句之前,而且必须与goto语句处在同一个函数或方法中。

2. 空语句

3. 逗号运算符

优先级列表的底层是逗号运算符。结果是最右边的表达式值。

4. sizeof运算符

参数可以是变量、数组名称、基本数据类型、对象、派生类或表达式
sizeof (obj1) 结果是4,也就是对象的指针。
如果sizeof(*obj1),可能大于4,看它的成员变量加上isa成员。
sizeof(data) / sizeof(sizeof(data[0])
data必须是数组,不能是指针哦,不是形参数组哦。

5. 命令行参数

当运行系统调用main函数时,传递两个参数。一个是参数个数,一个是指针数组指针,具体的参数。
argv[0]就是程序名称。后边就是实际带的参数。
如lookup是一个可执行程序。那么loopup aerie
那么argc = 2; argv[0] = lookup, argv[1] = aerie;
记住:命令行参数总是存储为字符串的。
可以使用转换scanf、atof、atoi、strtod、strtol

13.7 工作原理

1. 实例变量存储在结构中

定义一个新类和它的实例变量中,这些实例变量实际存放在一个结构中。继承的成员之一就是名为isa的保护成员。运行时系统只需通过查看isa成员,就可以确定对象的类。

2. 对象变量实际上是指针

3. 方法是函数,而消息表达式是函数调用。

编译器通过类名称和方法名称的组合为每个函数产生一个唯一的名称。

4. id类型是通用指针类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值