使用本地c/c++提升iOS性能之二

基本的c和c++编程

创新互联公司是一家专业提供广饶企业网站建设,专注与成都做网站、成都网站制作、html5、小程序制作等业务。10年已为广饶众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。

我将会引导你学习一些简单的c/c++课程,让你对它有一个基本的了解。Objective-C和c/c++有很多共同点,所以在本章你不需要学习很多新的概念。理解c/c++同样能够帮助你更好的编写Objective-C,因为Objective-C是C的一个超集。

c编程

c++同样是c的超集,所以你必须先学会如何使用c,然后在接下来的部分学习c++。我只会讨论使用c编程和iPhone编程不同的那部分。

基本数据类型和函数

c的数据类型很少:integer,floating point,double precision floating point 和characters。在不同的操作系统中,每一种数据类型的二进制位是不同的,甚至在iOS的不同版本中也不同。下面的是每种数据类型的取值范围,但是你不应该太过依赖于这些信息,尤其是在做重要决定的时候:

  • char:-128到127

  • integer:-32768到+32767

  • float:3.4 e-38 到 3.4 e+38

  • double:1.7 e -308 到 1.7 e +308

还有很多修饰符可以应用带这些基本类型上;例如,short和long可以用在integer上。

short int sh;

long int counterLong;

使用这些修饰符的目的是为integer提供一个更小或更大的范围;例如,short是16位,long是32位。iOS编译器能确保short不比int长,long不比int短。

你也可以使用signed和unsigned修饰符。如果你没有指定任何signed或unsigned,编译器默认使用signed。使用unsigned修饰符,能让数据范围扩大一倍。例如,integer的范围从0到65535.

通常你只需使用integer。如果你想存储一个很大的integer,就添加long修饰符。使用short覆盖int,内存优化非常小,你基本上可以忽略它。

注意:如果你使用Objective-C,你应该使用NSInteger,NSUInteger,和CGFloat。这些是苹果内置的包装类,它们封装了底层的实际数据结构。


c没有Boolean数据类型,但是Objective-C有。在c中,如果一个Boolean语句返回true,值是1;否则是0.例如 2==2将返回1,而 2==3将返回0。为了增强代码的可读性,你可能需要定义两个Boolean宏,类似这样:

   #define TRUE 1

   #define FALSE 0

   int t = (1 == 1);

   if (t == TRUE) {

       // do your work here

   }

尽管c函数和Objective-C函数看起来不同,但是你依然需要返回一个值和接收参数。下面是两个c函数的例子:

int pi_value() {

   return 3.14;

}

int add_number(int n1, int n2) {

   return n1 + n2;

}

指针

指针在c编程中是非常重要的。在Objective-C中,你通常会看到Objective-C有同样的指针概念和语法,例如NSMutableArray *myArray = [NSMUtableArray array]。但是,你不需要知道底层内存的细节,因为在Objective-C中指针可以很简单的认为它是一个对象。但是,如果使用c,你要做的事情将更多,c中指针的概念也更加复杂。


内存指针概念


主存可以看做是一个cell的数组,每一个cell看做是一个字节,每一个数据item存储在cells的group中。一个char存储在一个cell,一个integer存储在两个cell中,而一个long存储在4个cell中。每一个cell都可以被数字化,因此每一个变量将有一个内存地址来存储数据。


使用本地c/c++提升iOS性能  之二

图 9-1 内存指针概念


指针是一个变量,它保存了另一个变量的内存地址。例如,图9-1变量p里面的数据保存了变量c的内存地址。所以我们说,p指向了c,你可以用语句 p = &c 来表示它;&操作符返回变量c的内存地址,然后赋值给p。&只能应用在内存中的变量,数组和对象,不能用在表达式或常量上。指针的另一个操作符是*;当它应用到指针,指针操作符然后给定地址内存中的内容。这个过程通常称为解引用。这边有一个源代码显示了是如何进行工作的:


int x = 1, y = 2, a[3];
int *ip; // ip is a pointer that can only point to integer

ip = &x; // ip now points to x
y = *ip; // y is now 1, because you return the data pointed by ip*ip = 0; // x is now 0, I set the data pointed by p to be 0
ip = &a[0]; // ip now points to the first element of array a

值传递和引用传递

在c编程中,你参数传递有两种方式:值传递和引用传递。通过值传递把参数传递给函数是通常的方式。

int add(int t1, int t2) {

   return t1 + t2;

}

然而,值传递是不起作用的,如果你想要交换两个变量的值:

void swap(int x, int y) {

   int temp;

  temp = x;  

   x = y;  

   y = temp;

}

int main() {

   int x = 3, y = 4;

   swap (x, y);

}

问题是在函数返回后,里面的两个变量值并没有交换。当swap方法被调用的时候,x和y的值会被拷贝然后再传递给函数swap(3, 4)。因此,原始的变量值并没有改变。

如果你想要改变存储在变量x和y的内部值,你需要使用引用传递。通过引用传递,x和y的内存地址被传递进来。使用x和y的内存地址,你能够非常简单的修改存储在她们内存的值了。

void swap(int *px, int *py) {
   int temp;
   temp = *px; // temporarily store the value inside the memory of x

   *px = *py; // set the value inside the memory of x.
   *py = temp; // set the value inside the memory of y.

}

int main() {
   int x = 3, y = 4;

   swap (&x, &y);

}

图 9-2 能够让你更好的理解这个过程。

使用本地c/c++提升iOS性能  之二

高级数据类型

在c中还有一些高级数据类型:array(数组),string(字符串)和struct(结构体)。这些在Objective-C中都是支持的,但是你应该谨慎的使用,因为会使得代码难以理解,后续维护也变得更加困难。所有这些数据结构在Objective-C中都有对应的包装类,使得代码更加面向对象。但是,在很多情况下,你仍然需要使用c数据结构来提升性能或处理来自c/c++库的调用结果。

Array数组

在Objective-C中,你通常会使用NSArray或NSMutableArray对象来表示一个数组。但是,在c中,你没有这些概念,因此你应该集中在数组的基本概念上。在c中为了定义一个数组,你需要提前知道数组的长度,类似这样的定义:

int a [10]; // an array with maximum ten elements
a[0], a[1], a[2] ... a[9]is the first, second ... tenth elements of the array

指针和数组有非常密切的关系。

int *pa;

pa = &a[0];

这个指针赋值代码将pa指向数组的第一个元素。根据指针那部分解释的,赋值语句 x = *pa,x包含了a[0]的值。

你可以通过简单的算术运算来移动指针指向数组内的不同元素,pa+1会返回下一个元素的地址,pa-1返回上一个元素的地址。图9-3展示了指针在数组内部的算术运算。

使用本地c/c++提升iOS性能  之二

这些计算并不依赖于数组内存变量的类似或大小。因此,(pa + i)将返回数组中的第i个元素的地址。另一个在数组和指针之间非常重要的关系是你可以使用 *(aa + i)来引用a[i]。

在数组和指针之间有一个不同点:指针是一个变量,所以pa = a和pa++都是合法的。然而,a = pa和a++是不合法的。

String字符串

在c中字符串常量,例如 "I am Khang",一个以'\0'结尾的字符数组,这样程序就能够找到数组的结束部分。因为string是一个字符数组,你可以简单的将它赋值给指针。

char *pmessage;
pmessage = "I am Khang";

你可以把string看做是一个正常的数组或指针那样进行操作,如下面的源代码:

void my_string_copy (char *s, char *t) {

   while (*s++ = *t++) ;

}

my_string_copy函数是非常简单的;它有两个字符指针,将string t(通过字符指针来表示)中的字符元素赋值给赋值给string s。


注意:当你把数组作为一个参数传递给函数时,c会自动的将它转换为指向数组的指针。

这里有另一个例子,使用了字符数组,但是并没有使用指针,它展示了数组和指针的内部转换:

int my_string_length(char *s) {

   int i = 0;
   while (s[i] != '\0') {

           i++;

   }

   return i;

}


当前文章:使用本地c/c++提升iOS性能之二
网页链接:http://ybzwz.com/article/jhcgdj.html