C 指向双指针

C 指向双指针,c,pointers,C,Pointers,我正在写一个以双指针作为参数的函数。我注意到像这样的表达式char*tmp=arr[I];work,其中arr是char**arr指针。整个函数如下所示: void string_sort(char** arr,const int len,int (*cmp_func)(const char* a, const char* b)) { for (int i = 0; i < len; ++i) { for (int j = i + 1; j < len

我正在写一个以双指针作为参数的函数。我注意到像这样的表达式char*tmp=arr[I];work,其中arr是char**arr指针。整个函数如下所示:

void string_sort(char** arr,const int len,int (*cmp_func)(const char* a, const char* b))
{
    for (int i = 0; i < len; ++i)
    {
        for (int j = i + 1; j < len; ++j)
        {
            if(cmp_func(arr[i], arr[j]) > 0)
            {
                char *tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
        }
    }
}

我的问题是-为什么arr[i]被认为是地址而不是去引用的指针?我知道一个双指针指向另一个指针的地址,但我不明白为什么这个语法是有效的。你能给出一个没有类似数组语法的等价表达式的例子吗

此语法有效,因为arr[i]与*arr+i完全相同。顺便说一句,这也是一个不使用数组下标语法的示例

…为什么arr[i]被视为地址而不是解引用指针


是的,arr[i]是一个取消引用的指针,如上所述。它也是一个地址,因为当您取消引用指向指针字符**arr的指针时,您会得到一个指针-一个地址。

此语法有效,因为arr[i]与*arr+i完全相同。顺便说一句,这也是一个不使用数组下标语法的示例

…为什么arr[i]被视为地址而不是解引用指针

是的,arr[i]是一个取消引用的指针,如上所述。它也是一个地址,因为当您将指针解引用到指针字符**arr时,您会得到一个指针-一个地址。

给您

#include <stdio.h>

int main(void) 
{
    char *s = "Hello";

    printf( "%p -> %s\n", ( void * )s, s );

    char **t = &s;

    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )*t, *t );
    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )t[0], *t );

    return 0;
}
这是指针s指向字符串文字Hello的第一个字符

指针t指向指针s,而指针s又指向字符串文本Hello的第一个字符

例如,如果您有这样一个声明

char *s = "Hello";
然后表达式s[0]和*s都具有char类型,并产生字符串文本的第一个字符“H”

另一个例子。如果你有一个整数数组

int a[] = { 1, 2, 3, 4, 5 };
然后它的元素数量可以如下计算

sizeof( a ) / sizeof( a[0] )
或者

sizeof( a ) / sizeof( *a )
[尽管你甚至可以这样写

sizeof( a ) / sizeof( a[1000] )
因为使用的表达式没有计算。重要的是int类型的对象的大小。所以您也可以编写

sizeof( a ) / sizeof( int )
-结束语]

给你

#include <stdio.h>

int main(void) 
{
    char *s = "Hello";

    printf( "%p -> %s\n", ( void * )s, s );

    char **t = &s;

    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )*t, *t );
    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )t[0], *t );

    return 0;
}
这是指针s指向字符串文字Hello的第一个字符

指针t指向指针s,而指针s又指向字符串文本Hello的第一个字符

例如,如果您有这样一个声明

char *s = "Hello";
然后表达式s[0]和*s都具有char类型,并产生字符串文本的第一个字符“H”

另一个例子。如果你有一个整数数组

int a[] = { 1, 2, 3, 4, 5 };
然后它的元素数量可以如下计算

sizeof( a ) / sizeof( a[0] )
或者

sizeof( a ) / sizeof( *a )
[尽管你甚至可以这样写

sizeof( a ) / sizeof( a[1000] )
因为使用的表达式没有计算。重要的是int类型的对象的大小。所以您也可以编写

sizeof( a ) / sizeof( int )

-结束注释]

因为arr是char**,所以arr[i]是char*。它是一个未引用的指针,但因为它指向其他指针,所以它也是一个字符的地址。好的,所以*arr+i=*&i=i,但是**arr+i=**arr+i=*i。我一点也不知道你在这里想说什么。不,没有意义上的*arr+i=*&i*arr+i是写入arr[i]的另一种方式,即数组arr的第i个元素,或超出arr起始地址的内存i元素块的内容。由于arr是char**,因此arr[i]是char*。它是一个未引用的指针,但因为它指向其他指针,所以它也是一个字符的地址。好的,所以*arr+i=*&i=i,但是**arr+i=**arr+i=*i。我一点也不知道你在这里想说什么。不,没有意义上的*arr+i=*&i*arr+i是写入arr[i]的另一种方式,即数组arr的第i个元素,或超出arr起始地址的内存i元素块的内容。