Objective-C中int**类型(指代数组)方法参数使用咨询
Hey there! 作为习惯Java和Swift的开发者,刚碰Objective-C的指针确实容易头大——毕竟这俩语言都把指针封装得明明白白,根本不用咱们操心内存地址那档子事。我来给你把int*和int**的用法掰扯清楚,尤其是你提到的int**作为数组的场景~
int* 到底是什么? 在Objective-C里,int*就是指向int类型变量的指针——你可以把它理解成一个“存储内存地址的变量”,这个地址对应的内存里存着一个int值。对你来说,类比Java/Swift的话,有点像“能直接修改原变量值的引用”:
比如你要传递一个int给方法,让方法能修改它的值,就会用int*:
// 定义一个修改int值的方法 - (void)updateNumber:(int*)numPtr { *numPtr = 100; // 用*获取指针指向的内存,修改里面的值 } // 调用方法 int myNum = 10; [self updateNumber:&myNum]; // &myNum是取myNum的内存地址,传给指针参数 NSLog(@"修改后的myNum:%d", myNum); // 输出100
当然,int*也可以指向一维int数组的第一个元素——这时候它的用法和Java/Swift的数组几乎一样:
int nums[] = {1,2,3,4}; int* numArrayPtr = nums; // 数组名本身就是指向第一个元素的指针 // 用下标访问,和Java完全一样 NSLog(@"第二个元素:%d", numArrayPtr[1]); // 输出2 // 或者用指针偏移的方式 NSLog(@"第三个元素:%d", *(numArrayPtr + 2)); // 输出3
int** 作为数组的用法 你遇到的接口里用int**指代数组,最常见的场景是方法需要给你返回一个动态分配的int数组——毕竟Java/Swift里直接return数组就行,但C/OC里如果方法要给外部分配内存并返回数组,就得用指针的指针来实现。
举个实际的例子,假设接口方法是这样的:
// 方法说明:返回一个int数组,数组地址通过arrayOut输出,长度通过countOut输出 - (void)fetchIntArray:(int**)arrayOut count:(int*)countOut { // 先确定数组长度 *countOut = 3; // 分配内存:3个int的空间 *arrayOut = malloc(*countOut * sizeof(int)); // 给数组赋值 (*arrayOut)[0] = 10; (*arrayOut)[1] = 20; (*arrayOut)[2] = 30; }
你调用的时候要这么写:
int* resultArray = NULL; // 先初始化一个空指针 int arrayCount = 0; [self fetchIntArray:&resultArray count:&arrayCount]; // 传指针的地址(&resultArray就是int**类型) // 现在就能像用普通数组一样用resultArray了 for (int i = 0; i < arrayCount; i++) { NSLog(@"数组第%d项:%d", i, resultArray[i]); } // !重要!:因为是用malloc分配的C风格内存,用完必须释放,否则会内存泄漏 free(resultArray); resultArray = NULL; // 避免野指针
为什么要用int**?简单说:如果方法参数是int*,那方法里修改的只是这个指针的副本,外面的resultArray根本不会变。而int**是指向指针的指针,方法里可以直接修改外面那个指针变量的地址,让它指向新分配的数组——这就相当于Java里你把数组引用放到一个List里,方法修改List里的引用,外面就能拿到新数组。
另外,int**也用来表示二维int数组(也就是数组的数组),用法是这样的:
// 创建一个2行3列的二维数组 int** twoDArray = malloc(2 * sizeof(int*)); // 先分配2个int指针的空间 for (int i = 0; i < 2; i++) { twoDArray[i] = malloc(3 * sizeof(int)); // 每行分配3个int的空间 for (int j = 0; j < 3; j++) { twoDArray[i][j] = i*3 + j; // 赋值 } } // 访问元素,和Java的二维数组写法一样 NSLog(@"[1][2]的值:%d", twoDArray[1][2]); // 输出5 // 释放内存:先释放每行,再释放外层 for (int i = 0; i < 2; i++) { free(twoDArray[i]); } free(twoDArray); twoDArray = NULL;
int*:要么用来传递可修改的单个int值,要么作为一维int数组的指针。int**:最常用在方法返回动态数组的场景,也可以表示二维int数组。- 记住C风格内存要手动管理:malloc分配的内存必须用free释放,别像Java/Swift那样等着GC~
内容的提问来源于stack exchange,提问作者Joey Nash

