这个指针指向C中指针语句的含义是什么?

时间:2017-10-23 12:31:59

标签: c pointers declaration pointer-to-pointer

int **arr = (int **)malloc(r * sizeof(int *));

我该如何解释上述C代码的含义?

2 个答案:

答案 0 :(得分:5)

appearance的调用:

malloc()

int **arr = (int **)malloc(r * sizeof(int *)); 的{​​{1}}指针分配空间,并返回指向分配的r。然后将此指针强制转换为int并分配给void *int **是指向arr的指针。因此int指向分配区域的第一个元素,它是指向arr的指针。这样的代码可以用于创建“锯齿状”数组,其中数组的每一行是分开分配的;这意味着分配在内存中可能不是连续的,因此这不是真正的2d数组。请参阅Correctly allocating multi-dimensional arrays以了解详情。

但上述被认为是不好的风格。最重要的是,应尽可能避免使用显式类型作为int运算符的参数:

sizeof

如果int **arr = (int **)malloc(r * sizeof *arr); 的类型在代码生命周期的某个时刻发生变化,则不易出错,并且更容易维护。

此外,there is no need to cast the result of malloc() in C,所以这个演员阵容是多余的,只会使代码混乱:

arr

作为最后的改进,我更倾向于在这种情况下放置int **arr = malloc(r * sizeof *arr); 表达式:

sizeof

这在上面的特定情况下是无用的改变,但是当有额外的乘法时,例如:

int **arr = malloc(sizeof *arr * r);

这保证了算法的执行类型至少与int **arr = malloc(sizeof *arr * r * n); 一样宽,从而降低了整数溢出的风险(size_t整数溢出导致C中的未定义行为),并且可能会减少signed整数环绕的风险(明确定义,但可能是意外或不受欢迎)。

答案 1 :(得分:2)

int **arr = (int **)malloc(r * sizeof(int *));

int * [r]类型数组的动态分配,rint *元素的数组,其类型为#include <stdio.h> int main(void) { char * s[] = { "Hello", " ", "user292174" }; const size_t N = sizeof( s ) / sizeof( *s ); char **p = s; for ( size_t i = 0; i < N; i++ ) printf( "%s", p[i] ); putchar( '\n' ); return 0; }

为了使声明更清晰,请考虑以下简单程序

Hello user292174

它的输出是

int

在程序中,而不是类型char,为了简单起见,使用了类型s

表达式中具有罕见异常的数组指示符将转换为指向其第一个元素的指针。

因为数组char *的类型是s,所以指向数组char **的第一个元素的指针将具有类型int *

在问题的原始声明的情况下,动态分配一个内存范围,该内存范围被解释为类型int **arr = (int **)malloc(r * sizeof(int *)); 的元素数组。并且将存在所存在的数组的第一个元素的范围的起始地址分配给指针。所以指针的类型应为int **。

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

int main(void) 
{
    size_t r = 2;
    size_t c = 3;

    int **arr = (int **)malloc( r * sizeof( int * ) );

    for ( size_t i = 0; i < r; i++ )
    {
        arr[i] = malloc( c * sizeof( int ) );
    }

    for ( size_t i = 0; i < r; i++ )
    {
        for ( size_t j = 0; j < c; j++ )
        {
            arr[i][j] = c * i + j;
        }
    }

    for ( size_t i = 0; i < r; i++ )
    {
        for ( size_t j = 0; j < c; j++ )
        {
            printf( "%d ", arr[i][j] );
        }
        putchar( '\n' );
    }


    for ( size_t i = 0; i < r; i++ )
    {
        free( arr[i] );
    }

    free( arr );

    return 0;
}

通常,这些分配用于在运行时计算数组的行数和列数时模拟二维数组。

例如

0 1 2 
3 4 5

程序输出

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

int main(void) 
{
    size_t r = 2;
    size_t c = 3;

    int ( *arr )[c] = (int **)malloc( sizeof( int[r][c] ) );


    for ( size_t i = 0; i < r; i++ )
    {
        for ( size_t j = 0; j < c; j++ )
        {
            arr[i][j] = c * i + j;
        }
    }

    for ( size_t i = 0; i < r; i++ )
    {
        for ( size_t j = 0; j < c; j++ )
        {
            printf( "%d ", arr[i][j] );
        }
        putchar( '\n' );
    }

    free( arr );

    return 0;
}

如果编译器支持可变长度数组,则可以一次分配二维数组。例如

HEADERS += ( dependent src headers )

porgram输出与上面显示的相同。