在Objective-C中有两个星号**是什么意思? [英] What does having two asterisk ** in Objective-C mean?

查看:119
本文介绍了在Objective-C中有两个星号**是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有一个星号*是一个指针,有两个**是什么意思?

I understand having one asterisk * is a pointer, what does having two ** mean?

我从文档中偶然发现了这一点:

I stumble upon this from the documentation:

- (NSAppleEventDescriptor *)executeAndReturnError:(NSDictionary **)errorInfo

推荐答案

它是指向指针的指针,就像在C语言中一样(尽管它的方括号语法很奇怪,但Objective-C却是基于它的):

It's a pointer to a pointer, just like in C (which, despite its strange square-bracket syntax, Objective-C is based on):

char c;
char *pc = &c;
char **ppc = &pc;
char ***pppc = &ppc;

以此类推,然后是无限的(或者直到您用完可变空间为止).

and so on, ad infinitum (or until you run out of variable space).

通常将指针传递给必须能够更改指针本身的函数(例如为可变大小的对象重新分配内存).

It's often used to pass a pointer to a function that must be able to change the pointer itself (such as re-allocating memory for a variable-sized object).

=====

在您请求一个示例来说明如何使用它之后,这是我为另一篇文章编写的一些代码来说明它.这是一个appendStr()函数,它管理自己的分配(您仍然必须释放最终版本).最初,您将字符串(char *)设置为NULL,并且函数本身将根据需要分配空间.

Following your request for a sample that shows how to use it, here's some code I wrote for another post which illustrates it. It's an appendStr() function which manages its own allocations (you still have to free the final version). Initially you set the string (char *) to NULL and the function itself will allocate space as needed.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void appendToStr (int *sz, char **str, char *app) {
    char *newstr;
    int reqsz;

    /* If no string yet, create it with a bit of space. */

    if (*str == NULL) {
        *sz = strlen (app) + 10;
        if ((*str = malloc (*sz)) == NULL) {
            *sz = 0;
            return;
        }
        strcpy (*str, app);
        return;
    }

 

    /* If not enough room in string, expand it. We could use realloc
       but I've kept it as malloc/cpy/free to ensure the address
       changes (for the program output). */

    reqsz = strlen (*str) + strlen (app) + 1;
    if (reqsz > *sz) {
        *sz = reqsz + 10;
        if ((newstr = malloc (*sz)) == NULL) {
            free (*str);
            *str = NULL;
            *sz = 0;
            return;
        }
        strcpy (newstr, *str);
        free (*str);
        *str = newstr;
    }

    /* Append the desired string to the (now) long-enough buffer. */

    strcat (*str, app);
}

 

static void dump(int sz, char *x) {
    if (x == NULL)
        printf ("%8p   [%2d]   %3d   [%s]\n", x, sz, 0, "");
    else
        printf ("%8p   [%2d]   %3d   [%s]\n", x, sz, strlen (x), x);
}

static char *arr[] = {"Hello.", " My", " name", " is", " Pax",
                      " and"," I", " am", " old."};

int main (void) {
    int i;
    char *x = NULL;
    int sz = 0;

    printf (" Pointer   Size   Len   Value\n");
    printf (" -------   ----   ---   -----\n");
    dump (sz, x);
    for (i = 0; i < sizeof (arr) / sizeof (arr[0]); i++) {
        appendToStr (&sz, &x, arr[i]);
        dump (sz, x);
    }
}

代码输出以下内容.您可以看到当前分配的内存用完扩展字符串的空间时指针如何变化(在注释处):

The code outputs the following. You can see how the pointer changes when the currently allocated memory runs out of space for the expanded string (at the comments):

 Pointer   Size   Len   Value
 -------   ----   ---   -----
# NULL pointer here since we've not yet put anything in.
     0x0   [ 0]     0   []

# The first time we put in something, we allocate space (+10 chars).
0x6701b8   [16]     6   [Hello.]
0x6701b8   [16]     9   [Hello. My]
0x6701b8   [16]    14   [Hello. My name]

# Adding " is" takes length to 17 so we need more space.
0x6701d0   [28]    17   [Hello. My name is]
0x6701d0   [28]    21   [Hello. My name is Pax]
0x6701d0   [28]    25   [Hello. My name is Pax and]
0x6701d0   [28]    27   [Hello. My name is Pax and I]

# Ditto for adding " am".
0x6701f0   [41]    30   [Hello. My name is Pax and I am]
0x6701f0   [41]    35   [Hello. My name is Pax and I am old.]

在这种情况下,您需要输入**str,因为您需要能够更改*str值.

In that case, you pass in **str since you need to be able to change the *str value.

=====

或以下命令,它对不在数组中的字符串进行展开的气泡排序(哦,太可惜了!).它是通过直接交换字符串的地址来实现的.

Or the following, which does an unrolled bubble sort (oh, the shame!) on strings that aren't in an array. It does this by directly exchanging the addresses of the strings.

#include <stdio.h>

static void sort (char **s1, char **s2, char **s3, char **s4, char **s5) {
    char *t;

    if (strcmp (*s1, *s2) > 0) { t = *s1; *s1 = *s2; *s2 = t; }
    if (strcmp (*s2, *s3) > 0) { t = *s2; *s2 = *s3; *s3 = t; }
    if (strcmp (*s3, *s4) > 0) { t = *s3; *s3 = *s4; *s4 = t; }
    if (strcmp (*s4, *s5) > 0) { t = *s4; *s4 = *s5; *s5 = t; }

    if (strcmp (*s1, *s2) > 0) { t = *s1; *s1 = *s2; *s2 = t; }
    if (strcmp (*s2, *s3) > 0) { t = *s2; *s2 = *s3; *s3 = t; }
    if (strcmp (*s3, *s4) > 0) { t = *s3; *s3 = *s4; *s4 = t; }

    if (strcmp (*s1, *s2) > 0) { t = *s1; *s1 = *s2; *s2 = t; }
    if (strcmp (*s2, *s3) > 0) { t = *s2; *s2 = *s3; *s3 = t; }

    if (strcmp (*s1, *s2) > 0) { t = *s1; *s1 = *s2; *s2 = t; }
}

int main (int argCount, char *argVar[]) {
    char *a = "77";
    char *b = "55";
    char *c = "99";
    char *d = "88";
    char *e = "66";

    printf ("Unsorted: [%s] [%s] [%s] [%s] [%s]\n", a, b, c, d, e);
    sort (&a,&b,&c,&d,&e);
    printf ("  Sorted: [%s] [%s] [%s] [%s] [%s]\n", a, b, c, d, e);
    return 0;
}

产生:

Unsorted: [77] [55] [99] [88] [66]
  Sorted: [55] [66] [77] [88] [99]

不用管排序的实现,只需要注意变量作为char **传递即可轻松进行交换.任何真正的排序都可能会作用于真正的数据数组上,而不是单个变量上,但这不是示例的重点.

Never mind the implementation of sort, just notice that the variables are passed as char ** so that they can be swapped easily. Any real sort would probably be acting on a true array of data rather than individual variables but that's not the point of the example.

这篇关于在Objective-C中有两个星号**是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆