1. 编译Object-C程序的命令
clang -fobjc-arc -framework Foundation 源程序名
2. Object-C程序有一个固定的格式
程序,总是从主函数入口。
int main(int argc, char* agrv[])
{
@autoreleasepool {
}
}
3.流程控制
顺序结构:
只有前一步完成,才能执行下一步。
后面的语句,必须以前面的语句为基础。
不加任何控制,程序自然就是顺序结构。
分支结构:
根据某些情况,选择执行某一支,如果条件不满足,选择执行另一支。
循环结构:
要达到某个目的,在目的达到之前,会多次重复做某些事情。
分支结构
如果 ... 否则 ...
if分支,完整语法为:
if(条件1)
{
条件执行体
}
else if(条件2) 这个 else if 可以出现0~N次。
{
条件执行体
}
...
else {
条件执行体
}
注意点:
1. Object-C/C并不严格要求if的条件表达式是逻辑表达式,Object-C/C语言会把所有非空、非0,都当成“真”处理。
2. 如果条件执行体只有一条语句,花括号可以省略。
如果省略了花括号,if条件只控制到紧根if条件的第一个分号为止。
一般建议,总是保留条件体的花括号,这样可以保持较好的可读性。
3. else本身就是一种条件。
else代表了对前面条件的取反。
当我们有多个else if时,记住要先处理范围小的条件。
switch分支
switch(表达式)
{
case 值1: case块,可以出现很1到N次
break;
case 值2:
break;
default: default块,可以出现0到1次。default代表与前面任意case值都不相等。
break;
}
程序会先对表达式进行求值,如果表达式等于后面哪个case块的值,程序就执行哪个case块。
如果表达式的值与任意的case值都不相等,那么程序就执行default块。
switch分支是对表达式的值进行精确匹配,它不能用于判断范围。
关于switch分支,有如下注意点:
1. switch中的表达式只能是short、int、long、long long、char、枚举类型。
2. switch表达式中省略了break之后导致的贯穿。
如果省略了break,switch会从第一个与表达式值相等的case块开始执行,接着程序会接续向下执行所有的case块,
在遇到break之前,程序不会判断case值与表达式是否相等,而是直接执行case快的代码。
循环结构
用于控制计算机多次重复执行某一段代码。
对于循环,有一个基本规则:循环条件一定要有终止循环的时候,否则就变成了无限循环(死循环)。
循环结构有如下几种:
while循环
while( 条件 )
{
循环体
}
1. 程序每次进入执行循环体之前,会先判断“条件”,如果条件为真,程序就执行循环体;如果条件为假,程序就跳出循环体。
Object-C/C并不严格要求while的条件表达式是逻辑表达式,Object-C/C语言会把所有非空、非0,都当成“真”处理。
条件执行次数 = 循环体执行次数 + 1
2. 如果循环体只有一条语句,花括号可以省略。
如果省略了花括号,while条件只控制到紧跟while条件的第一个分号为止。
一般建议,总是保留循环体的花括号,这样可以保持较好的可读性。
do while循环
do {
循环体
}
while(条件);
1. 程序不管什么,先把循环体执行一次。
接下来,程序会判断条件,如果条件为真,程序就会去执行循环体;否则跳出循环体;
条件执行次数 = 循环体执行次数
区别是:do...while循环会把循环体先执行一次,不管循环条件为真还是假。
for循环
功能最强大、而且最简洁的循环,因此用的也是最多的。
for( [初始化语句] ; [循环条件] ; [迭代语句] )
{
// 循环体
}
如果省略了循环条件,循环条件默认为真。
在循环开始之前,初始化语句执行一次。而且仅执行一次。
进入循环体之前,会先判断循环条件,如果循环条件为真,进入并执行循环体。
直到最后一次,程序判断循环条件为假,不再进入循环体,而是跳出循环体。
每次循环体执行完成之后,for循环会自动执行循环体。
初始化语句执行次数: 1
循环条件执行次数 - 1 = 迭代语句执行次数 = 循环体执行次数
for循环与while循环有如下关系:
[初始化语句]
while ( 循环条件 )
{
// 循环体
[迭代语句]
}
注意点:
1. 如果循环体只有一条语句,花括号可以省略。
如果省略了花括号,for循环只控制到紧跟for条件的第一个分号为止。
一般建议,总是保留循环体的花括号,这样可以保持较好的可读性。
2. 对于for循环,在for循环的初始化语句中声明的循环计数器只在该循环内有效。
3. 尽量避免在for循环的循环体内改变循环计数器的值。
对于for循环而言,一般建议在迭代语句中控制循环计数器的值,避免在循环体内改变循环计数器的值。
4. for循环的初始化语句可同时初始化多个变量,只要它们的类型相同即可。
迭代语句也可以包含多个语句,但多个语句之间用逗号隔开。
嵌套循环:循环里再放循环,此时内循环会被当成外循环的一条执行语句。
嵌套循环中最里层的循环体的执行次数 = N(外层循环的执行次数) * M (内层循环的执行次数)
控制循环结构:
C提供了如下两个关键字:
break:跳出循环。在循环中,如果遇到break,程序就会直接跳转到循环体的花括号之后。
break可用于跳出死循环。
continue:忽略本次循环剩下的语句,重新开始下一次循环。
执行循环体的时候,如果遇到了continue语句,程序就会忽略本次循环中位于continue以后的语句。
结论:如果continue是循环体的最后一条语句,该continue语句没有任何意义。
return也可以用于控制循环——但return本身是用于结束函数、方法。
如果程序使用return来结束了函数或方法,该函数、方法中的循环都会立即被终止。
goto语句
在以前,goto可以任意跳转,goto几乎可以代替所有分支、循环。
goto会导致程序的可读性大幅降低。
有时候,程序希望在嵌套循环的里层循环直接终止外层循环,此时就可以考虑使用goto完成。
4.数组(Array)
很多时候,程序中有多个类型相同,功能类似的数据需要存放时,此时即可考虑使用数组,而不是普通的变量。
一旦有了数组之后,数组就相当于多个类型相同的变量——这个就叫数组的元素。
换句话来说,每个数组元素,就是相当于一个变量。
定义数组的语法:
<元素类型> 数组名[长度];
- 局部数组:
定义数组之后,所有数组的值是不可靠的。
程序在使用局部数组之前,一定要先对局部数组的每个元素执行初始化!否则你的程序是不可靠——而且编译器不会报错的。
定义局部数组的长度可以变量、表达式。当然也可以常量、直接量。
- 全局数组:
定义数组之后,所有数组的值是可靠的,全部是广义的0.
全局数组要求定义数组时指定的长度必须是常量(用const修饰,定义之后以后不允许重新赋值)或者直接量(50、100、4)
使用数组:
每个数组元素,就相当于一个变量。
操作数组元素的方式: 数组[下标] , 第一个元素的下标为:0. 最后一个元素的下标为: 长度 - 1
有一个方法来计算数组的长度: sizeof - 获取某个东西在内存中所占用的字节数。
sizeof(数组) / sizeof(数组元素)
使用数组元素:数组变量[下标], 每个数组元素就相当于一个普通变量,程序即可对该变量赋值,也可访问变量的值。
C的数组,是静态数组。C的数组相当于是一个常量。因此程序不允许对数组变量赋值。
C的数组一旦在内存中被分配出来之后,该数组所占的内存空间是固定的,既不允许改变位置,也不允许改变大小。
多维数组:
一般来说,学到二维数组就足够了。
程序底层,并没有真正的多维数组,多维数组其实是不存在。
多维数组数组的本质,其实依然是一维数组,只不过其元素又是数组。比如:二维数组的元素,其实就是一维数组。
定义多维数组:
类型变量[长度][长度];
5.C的字符串和字符数组
C并没有提供字符串这种数据类型,C只提供了字符类型,而且C的字符只能存放ASCII字符(英文字符、也包含数字、英文标点)。
字符串,多个字符连在一起。C语言使用字符数组来存放字符串。
补充:由于C的字符不能保存中文字符,因此C的字符串也不能保存中文字符。
Object-C专门问提供了NSString类,这个类是Object-C的字符串,它可以保存中文的。
C语言为了简化字符串的处理,制定了如下两个规则:
- 程序可以直接使用字符串来初始化字符数组。这样就简化了字符串的初始化过程。
如果你没有指定字符数组的长度,该字符数组的长度,总是等于字符串中字符的个数+1,程序会在字符数组的最后保存一个结束符:\0
- 当程序使用%s来输出字符数组(字符串),输出函数将会输出到结束符(\0)时自动停止。