//
;/*
注释开始和*/
注释结束,需要指出的是多行注释不可以嵌套,在/**/
多行注释代码块内,不能再次使用/**/
添加多行注释;Objective-C语言里的分号(;)、花括号({})、方括号([])、圆括号(())、空格、圆点(.)都具有特殊的分隔作用,因此被统称为分隔符。
分号
Objective-C语言里语句的分隔不是使用回车来完成的,而是采用分号(;)作为语句的分隔,因此,每个Objective-C 语句必须使用分号作为结尾。Objective-C 程序允许一行书写多行语句,每个语句之间以分号隔开即可,单从程序的可读性角度来看,应该避免在一行书写多个语句;一个语句也可以跨多行,只要在最后结束的地方使用分号结束即可。
花括号
花括号的作用就是定义一个代码块,一个代码块指的就是" {" 和" }" 所包含的一段代码,代码块在逻辑上是一个整体。
方括号
圆括号
空格
Objective-C 语言中的空格包含空格符(Space)、制表符(Tab) 和回车(Enter) 等。除此之外,Objective-C 源程序还会使用空格来合理缩进代码,从而提供更好的可读性。
圆点
标识符,就是用于给程序中变量、类、方法命名的符号。规则如下:
Objective-C语言其实就是C语言的超集,因此,它支待的数据类型与C 基本相似,大致分类如下:
数据类型:
需要指出的是,Objective-C 并没有硬性规定各种整型在内存中所占的空间。通常来说,Objective-C 要求long long 型所占用的内存空不小于long 型所占用的内存空间,long 型所占的内存空间应该不小千int 所占的内存空间,int 型所占的内存空间应该不小于short 型所占用的内存空间。
经验证,在64位Mac系统上,iPhone 8 Plus,short占2字节,int占4字节,long占8字节,long long占8字节。
size_t stSize = sizeof(short); size_t intSize = sizeof(int); size_t ltSize = sizeof(long); size_t llSize = sizeof(long long); NSLog(@"\nshortSize = %zu\nintSize = %zu\nlongSize = %zu\nlonglongSize = %zu",stSize,intSize,ltSize,llSize); 打印: shortSize = 2 intSize = 4 longSize = 8 longlongSize = 8
Objective-C 中整数常量有3 种表示方式:十进制、八进制和十六进制,其中八进制的整
数常量以0开头,十六进制的整数以0x或者0X开头,其中1015分别以af ( 此处的a~f不区分大小写)来表示。
// 以0开头的整数常量是八进制的整数 int octalValue = 013; // 以0x或者0X开头的整数常量是十六进制的整数 int hexValue = 0x13; NSLog(@"\noctalValue = %d\nhexValue = %d",octalValue,hexValue); 打印: octalValue = 11 hexValue = 19
Objective-C 还允许在上述4 种整型前面添加unsigned 关键词,将它们变成无符号整型,无符号整型的最高位不是符号位,而是数值位,因此无符号整数不能表示负数。但与此同时,无符号整型的最大值比对应的普通整型的最大值大一倍。比如,short int 的取值范围是-2^15 ~ 2^15 - 1, 而unsigned short 的取值范围则是0~2^16 - 1。
使用NSLog()函数非常简单,它的第一个参数应该是一个字符串常量,该字符串中可使用%格式的占位符,这个占位符将会由对应的变量填充。
%格式的占位符如下:
%d:以带符号的十进制形式输出整数(正数不输出符号);
%o:以八进制无符号形式输出整数(不输出0 前缀);
%x:以十六进制无符号形式输出整数(不输出0x 前缀);
%u:以无符号十进制形式输出整数;
%c:以字符形式输出,只输出一个字符;
%s:输出C 风格的字符串;
%f:以小数形式输出浮点数,默认输出6 位小数;
%e:以指数形式输出浮点数,数字部分默认输出6 位小数;
%g:自动选用%f 或%e 其中之一,保证输出宽度较短的格式,并且不会输出无意义的0;
%p:以十六进制形式输出指针变量所代表的地址值;
%@:输出Objective-C 的对象;
%zu:C99 ,输出 size_t 类型
/* 32位 */ typedef unsigned int size_t; typedef int ssite_t; /* 64位 */ typedef unsigned long size_t; typedef long ssize_t;
在%与格式字符之间,还可插入如下附加符:
int a = 56; NSLog(@"==%d==" , a); NSLog(@"==%9d==" , a); // 输出整数占9位 NSLog(@"==%09d==" , a); // 输出整数占9位,前边空位用0代替 NSLog(@"==%-9d==" , a); // 输出整数占9位,并且左对齐 NSLog(@"=%o==", a); // 输出八进制数 NSLog(@"==%x==", a); // 输出十六进制数 long b = 56; NSLog(@"%ld" , b); // 输出long int 型的整数 double dl = 2.3; NSLog(@"==%f==" , dl); // 以小数形式输出浮点数 NSLog(@"==%e==" , dl); // 以指数形式输出浮点数 NSLog(@"==%g==" , dl); // 以最简形式输出浮点数 NSLog(@"==%9f==" , dl); // 以小数形式输出浮点数,并且最少占用9位 NSLog(@"==%9.4f==" , dl); // 以小数形式输出浮点数,至少占用9位,小数点共4位 NSLog(@"==%9lf==" , dl); // 以小数形式输出长浮点数,并且最少占用9位 NSLog(@"==%9.4lf==", dl); // 以小数形式输出长浮点数,至少占用9位,小数点共4位 打印: 2019-02-17 16:02:37.414651+0800 StudyDemoProjectDemo[478:51240] ==56== 2019-02-17 16:02:47.162964+0800 StudyDemoProjectDemo[478:51240] == 56== 2019-02-17 16:02:47.162964+0800 StudyDemoProjectDemo[478:51240] ==000000056== 2019-02-17 16:02:50.546915+0800 StudyDemoProjectDemo[478:51240] ==56 == 2019-02-17 16:02:53.770814+0800 StudyDemoProjectDemo[478:51240] =70== 2019-02-17 16:02:54.635277+0800 StudyDemoProjectDemo[478:51240] ==38== 2019-02-17 16:02:57.499029+0800 StudyDemoProjectDemo[478:51240] 56 2019-02-17 16:03:00.236972+0800 StudyDemoProjectDemo[478:51240] ==2.300000== 2019-02-17 16:03:02.469281+0800 StudyDemoProjectDemo[478:51240] ==2.300000e+00== 2019-02-17 16:03:03.746471+0800 StudyDemoProjectDemo[478:51240] ==2.3== 2019-02-17 16:03:06.426914+0800 StudyDemoProjectDemo[478:51240] == 2.300000== 2019-02-17 16:03:29.924144+0800 StudyDemoProjectDemo[478:51240] == 2.3000== 2019-02-17 16:03:38.167223+0800 StudyDemoProjectDemo[478:51240] == 2.300000== 2019-02-17 16:03:42.453096+0800 StudyDemoProjectDemo[478:51240] == 2.3000==
字符型通常用于表示单个的字符,字符常量必须使用单引号(')引起来。Objective-C 的每个字符只占一字节,因此,单个的Objective-C 字符变量并不支待中文字符,中文字符占2个字节。
转义字符如下:
\b
:退格符;\n
:换行符;\r
:回车符enter;\t
:制表符tab;\"
:双引号;\'
;单引号;\\
;反斜线;不仅如此,char 类型的值也可直接作为整数型的值来使用,但它是一个8位的无符号整数,即全部是正数,取值范围是0-255。如果把一个在0~255范围内的int整数赋给char类型的变量,系统会自动把这个int整数当成char 类型来处理。
浮点类型有3种:float、double 和long double, 一般来说,float 型占用4 字节,double型变量占8 字节;而long double 则占16 字节(iPhone 8plus测试是8字节);
Objective-C 的浮点数有两种表示形式
必须指出的是,只有浮点类型的数值才可以使用科学计数形式表示。例如,51200 是一个int 类型的值,但512E2 则是浮点型的值。
除此之外,Objective-C 还提供了3 个特殊的浮点型数值:正无穷大、负无穷大和非数,例如,使用一个正数除以0.0 将得到正无穷大,使用一个负数除以0.0 将得到负无穷大,0.0除以0.0 或对一个负数开方将得到一个非数。必须指出的是,所有的正无穷大数值都相等,所有的负无穷大数值都相等;而非数不与任何数值相等,甚至和非数自己都不相等。
double d = 512000.f; double num1 = d/0.0f; double num2 = -d/0.0f; double num3 = 0.0f/0.0f; NSLog(@"正无穷大inf=%g",num1); NSLog(@"负无穷大-inf=%g",num2); NSLog(@"非数nan=%g",num3); NSLog(@"正无穷大比较%d",num1==1/0.0f); NSLog(@"负无穷大比较%d",num2==-1/0.0f); NSLog(@"非数比较%d",num3==num3); 打印: 2019-02-17 18:06:51.406790+0800 StudyDemoProjectDemo[563:72926] 正无穷大inf=inf 2019-02-17 18:06:51.407105+0800 StudyDemoProjectDemo[563:72926] 负无穷大-inf=-inf 2019-02-17 18:06:51.407216+0800 StudyDemoProjectDemo[563:72926] 非数nan=nan 2019-02-17 18:06:51.407306+0800 StudyDemoProjectDemo[563:72926] 正无穷大比较1 2019-02-17 18:06:51.407387+0800 StudyDemoProjectDemo[563:72926] 负无穷大比较1 2019-02-17 18:06:51.407468+0800 StudyDemoProjectDemo[563:72926] 非数比较0
枚举类型定义
enum season { spring = 4, summer, fall, winter }; // 使用枚举值 enum season mySeason; mySeason = summer; // 把枚举值当成无符号整数执行输出
NSLog(@“mySeason 的值:%u” , mySeason);
```
2. 定义匿名枚举类型时直接定义变量
``` enum {male, female} me, you; ``` 上面代码中定义了一个匿名枚举类型,并在定义该枚举类型时定义了两个变量:me和you,这两个变量都只能等于male 或female 其中之一。
关于枚举值的几点说明:
需要指出的是,虽然可以用整数值来代替枚举值,但实际编程中尽量不要使用整数值来代替枚举值,也不要使用枚举值来代替整数值-毕竟枚举值具有更好的可读性。
Objective-C 提供了一个BOOL 类型,BOOL 类型的值有YES 和NO 两个值,分别代表真和假。但需要指出的是,Objective-C 底层实际上使用signed char 来代表BOOL。而YES、NO两个值的底层其实就是1 和0。对于C 语言而言,所有的非零数都会被当成真,因此,YES 也会被当成真处理;而NO 的值是0, 因此,NO 也会被当成假处理。
有两种类型转换方式:自动类型转换和强制类型转换。
如果系统支待把某个基本类型的值直接赋给另一个基本类型的变量,则这种方式被称为自动类型转换。自动转换规则如下:
把整型类型(包括字符型)的变量和值赋值给浮点型变量,不会有太大的变化;
把浮点型类型的变量和值赋值给整型(包括字符型)变量,数值的小数部分会被直接舍弃;
当把取值范围大的变量值赋给取值范围小的变量时,可能发生溢出;
比如将int型变量33000赋值给short型变量时,short的取值范围是(-32768~32767),就会发生溢出,强制类型转换为16 位的short 类型,则需要截断前面16 位,只保留后16 位,余下16 位中最左边的是符号位。
当把取值范围大的变量或值转换为取值范围小的类型时,必须格外小心,因为非常容易引起信息丢失。
强制类型转换的运算符是圆括号()。
// 将浮点型强制转换成int型进行计算 int a = (int)2.3 + (int)122.2;
当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升:
Objective-C 语言中的运算符可分为如下几种:
+:加法运算符,+还可以作为字符串的连接运算符;
-:减法运算符,还可以作为求负的运算符号;
*:乘法运算符;
/:除法运算法;
除法运算符有些特殊,如果除法运算符的两个运算数都是整数类型,则计算结果也是整数,就是将自然除法的结果截断取整,例如,19/4 的结果是4,而不是5。
%:求余运算符;
它要求运算符两边的操作数都必须是整数,它的计算结果是使用第一个运算数来除以第二个运算数(不可以为0),得到一个整除的结果后,剩下的值就是余数。
++:自加;
这是一个单目运算符,运算符既可以出现在操作数的左边,也可以出现在操作数的右边,但出现在左边和右边的效果是不一样的。如果把++放在左边,则先把操作数加1, 然后才把操作数放入表达式中参与运算,如果把++放在右边,则先把操作数放入表达式中参与运算,然后才把操作数加1, 看如下代码:
int e = 1; int f = e++ + 6; NSLog(@"e = %d, f = %d",e,f); e = 1; f = ++e + 6; NSLog(@"e = %d, f = %d",e,f); 打印: 2019-02-17 19:09:44.544752+0800 StudyDemoProjectDemo[607:80323] e = 2, f = 7 2019-02-17 19:09:51.456103+0800 StudyDemoProjectDemo[607:80323] e = 2, f = 8
–:自减;
也是一个单目运算符,效果与++基本相似,只是将操作数的值减1。
Objective-C 使用" = " 作为赋值运算符。值得指出的是,赋值表达式是有值的,赋值表达式的值就是右边被赋的值。例如,NSString *str2 = str 表达式的值就是str。因此,赋值运算符支持连续赋值,通过使用多个赋值运算,可以一次为多个变量赋值:
int a; int b; a = b = 7;
Objective-C 虽然支持一次为多个变量赋值的写法,但这种写法会导致程序的可读性降低,因此不推荐这样写。
Objective-C 支持的位运算符有如下:
>>
:右位移运算符;第1运算数 | 第2个运算数 | 按位与 | 按位或 | 按位异或 |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
提示:
所有的数字在计算机底层都是以二进制形式存在的,原码是直接将一个数值转换成二进制数。但计算机以补码的形式保存所有的整数。补码的计算规则如下:正数的补码和原码完全相同,负数的补码是其反码+1;反码是对原码按位取反,只是最高位(符号位)保持不变。负数补码求原码:补码符号位不变,补码-1,再取反就是原码。
例子:
非运算
short a1 = -5; NSLog(@"~a1=%d",~a1); 打印: ~a1=4 原理解析: -5的原码: 10000000 00000101 -5的反码: 11111111 11111010 -5的补码: 11111111 11111011 -5非运算: 00000000 00000100(符号位0是正数,数值=4)
异或运算
short b1 = 5; short c1 = 9; NSLog(@"b1^c1=%d",b1^c1); 打印: b1^c1=12 原理分析: 5的补码: 00000000 00000101 9的补码: 00000000 00001001 异或运算:00000000 00001100(12)
位移运算符:
左移运算符是将运算数的二进制码整体左移指定位数,左移后右边空出来的位以0 来填充;
右移运算符为:>>,对于>>运算符而言,把第一个操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位来填充。即如果第一个操作数原来是正数,则左边补0; 如果第一个操作数原来是负数,则左边补1。
例子:
NSLog(@"5<<2=%d",5<<2); NSLog(@"-5<<2=%d",-5<<2); NSLog(@"5>>2=%d",5>>2); NSLog(@"-5>>2=%d",-5>>2); 打印: 5<<2=20 -5<<2=-20 5>>2=1 -5>>2=-2 原理分析:(以short类型为例) 5的原码: 00000000 00000101 5的补码: 00000000 00000101 5<<2: 00000000 00010100(20) 5>>2: 00000000 00000001(1) -5的原码: 10000000 00000101 -5的反码: 11111111 11111010 -5的补码: 11111111 11111011 -5<<2补码: 11111111 11101100 -5<<2反码: 11111111 11101011 -5<<2原码: 10000000 00010100(-20) -5>>2补码: 11111111 11111110 -5>>2反码: 11111111 11111101 -5>>2原码: 10000000 00000010(-2)
特殊:
1<<0(1)
1<<1(2)
1<<2(4)
1<<3(8)
总结:
当进行位移运算时,不难发现,左移n位就相当于乘以2的n次方,右移则是除以2的n次方(如果不能整除,实际返回的结果为小于除法结果的最大整数)不仅如此,进行位移运算不会改变操作数本身,它只是得到了一个新的运算结果, 而原来的操作数本身是不会改变的。
赋值运算符可与算术运算符、位移运算符结合,扩展成为功能更加强大的运算符。
+=
; x += y,对应x = x + y;-=
;*=
;/=
;%=
;|=
;&=
;^=
;<<=
;>>=
;x>>=y,对应x = x>>y;比较运算符用于判断两个变量或常量的大小,比较运算的结果是整数值(1 代表真、0 代表假)
>
;>=
;==
’a’返回1; 5.0 = 5也返回1。逻辑运算符用于操作两个布尔型的变量或常量。
&&
(与);必须前后两个操作数都是真才返回真,否则返回假。
||
(或);只要两个操作数中有一个真,就可以返回真,否则返回假。
!
(非);
只需要一个操作数,如果操作数为真,返回假;如果操作数为假,返回真。需要指出的是,Objective-C 并没有提供表示真、假的布尔型数据,Objective-C 通常会用1 代表真,用0 代表假。除此之外,Objective-C 会把任意非0 的数值当成真,0 才会被当成假。!5的值为0。
^
(异或);当两个操作数不同时才返回真,如果两个操作数相同,则返回假。
Objective-C 提供了逗号运算符,用于将多个表达式”连接”起来,而整个逗号表达式将返回最后一个表达式的值。语法格式如下:表达式1, 表达式2, 表达式3, ... , 表达式n
当我们需要将逗号表达式的值赋给指定变量时,千万不要忘了把整个逗号表达式用圆括号括起来。
int a = (3 * 4, 5 > 2) a的值为1
需要指出的是,并不是所有出现逗号的地方都是逗号表达式,比如前面程序中常用的输出语句:NSLog(@"%d, %d" , a, b);, 这条输出语句中的逗号只是用于分隔向NSLog()函数传入的多个参数,并不是逗号表达式。
三目运算符(?:)语法格式:(expression) ? if-true-statement : if-false-statement;
三目运算符的规则是:先对逻辑表达式expression 求值,如果逻辑表达式返回真,则执行并返回第二个操作数的值,如果逻辑表达式返回假,则执行并返回第三个操作数的值。
Objective-C 语言中的大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是它们是从右向左运算的。
运算符的优先级:
. () [] {} ->
;++ -- ~ ! *(取变量运算符) &(取地址运算符) sizeof
;(type)
;* / %
;+ -
;<< >>
;< <= > >=
;== !=
;&
;^
;|
;&&
;||
;?:
;= += -= *= /= &= |= ^= %= <<= >>=
;,
;虽然Objective-C 运算符存在这种优先级的关系,但并不推荐过度依赖这种运算符的优先级,否则会降低程序的可读性。因此注意以下两点。