温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2020-07-07 13:06:37 来源:网络 阅读:600 作者:iKingLai 栏目:移动开发

基本的c和c++编程


我将会引导你学习一些简单的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;

}






向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI