C-指向指针数组的指针 [英] C - pointer to pointer array

查看:100
本文介绍了C-指向指针数组的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习C,因为我陷入了指针章节.指向指针(** p)的指针的部分,用于处理2维数组.

I am learning C and as I got stuck at the pointer chapter. Particullary at the pointer to pointer ( **p ) part, used with processing 2 dimensional arrays.

以下函数生成一个2维数组,其所有元素均等于0.

The following function generates a 2 dimmensional array with all its elements equal to 0 .

double** example(int rows, int cols){
    static double tr[rows][cols];
    for(int i = 0; i < rows; i++)
       for(int j = 0; j < cols; j++)
            tr[j][i] = 0;
    return tr;
    }
int main(void){

    double **tr;
    int m = 2 ;
    int n = 2 ;

    tr = transpose(m, n);
    return 0;}

函数返回的tr是指向tr数组的第一个元素的双指针"吗?还是要其价值?另外,现在(在调用函数之后)如何在内存中** tr指向?的部分访问数组的元素?

Is the tr returned by the function a "double pointer" to the first element of the tr array ? Or to its value ? Also, now (after the the function was called) how do I access the elements of the array at the part of memory where **tr points to ?

有人可以向我解释这一切如何运作吗?还是建议我在这本书中写一篇文章或一章?

Can someone explain me how this all works ? Or suggest me an article or a chapter in a book that does ?

推荐答案

所提供的程序完全不正确.可变长度数组可能没有静态存储时间/根据C标准(6.7.6.2数组声明符)

The presented program is totally incorrect. A variable length array may not have static storage duration/ According to the C Standard (6.7.6.2 Array declarators)

2如果一个标识符被声明为具有可变修改的类型,则它 应为普通标识符(如6.2.3所定义),没有链接, 并具有块作用域或函数原型作用域. 如果 标识符被声明为具有静态或线程存储的对象 持续时间,它不能具有可变长度的数组类型.

2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

此外,指针类型double **double ( * )[cols](提供正确声明的数组将在表达式中转换为指针类型)不兼容.所以功能是错误的.

Moreover the pointer types double ** and double ( * )[cols] (to which the array provided that it was declared correctly is converted in expressions) are not compatible. So the function is wrong.

double** example(int rows, int cols){
    static double tr[rows][cols];
    for(int i = 0; i < rows; i++)
       for(int j = 0; j < cols; j++)
            tr[j][i] = 0;
    return tr;
    }

这里是一个演示程序,展示了如何处理可变长度数组.

Here is a demonstrative program that shows how to deal with variable length arrays.

#include <stdio.h>

void init( size_t rows, size_t cols, double a[rows][cols] )
//  or
//  void init( size_t rows, size_t cols, double a[][cols] )
//  or
//  void init( size_t rows, size_t cols, double ( *a )[cols] )
{
    for ( size_t i = 0; i < rows; i++ )
    {
        for ( size_t j = 0; j < cols; j++ ) a[i][j] = 0.0;
    }
}

void display( size_t rows, size_t cols, double a[rows][cols] )
//  or
//  void display( size_t rows, size_t cols, double a[][cols] )
//  or
//  void display( size_t rows, size_t cols, double ( *a )[cols] )
{
    for ( size_t i = 0; i < rows; i++ )
    {
        for ( size_t j = 0; j < cols; j++ ) printf( "%lf", a[i][j] );
        putchar( '\n' );
    }
}

int main(void) 
{
    while ( 1 )
    {
        size_t m, n;

        printf( "Enter numbers of rows and columns (0 - exit): " );

        if ( scanf( "%zu%zu", &m, &n ) != 2 || m == 0 || n == 0 ) break;

        double a[m][n];

        putchar( '\n' );

        init( m, n, a );
        display( m, n, a );

        putchar( '\n' );
    }

    return 0;
}

其输出可能看起来像

Enter numbers of rows and columns (0 - exit): 2 3

0.0000000.0000000.000000
0.0000000.0000000.000000

Enter numbers of rows and columns (0 - exit): 3 4

0.0000000.0000000.0000000.000000
0.0000000.0000000.0000000.000000
0.0000000.0000000.0000000.000000

Enter numbers of rows and columns (0 - exit): 0 0

在这两个函数中,第三个参数被调整为指针类型double ( *a )[cols].它与double **a不同.

Within the both functions the third parameter is adjusted to the pointer type double ( *a )[cols]. It is not the same as double **a.

例如,如果您要编写以下程序

If you will write for example the following program

#include <stdio.h>

#define M   2
#define N   3

int main(void) 
{
    int a[M][N] =
    {
        { 1, 2, 3 },
        { 4, 5, 6 }
    };

    int **p = ( int ** )a;

    p[0][0] = 10;

    return 0;
}

然后它将具有未定义的行为,因为p[0]认为存储在元素a[0][0]中的值(或存储在元素a[0][0]a[0][1]中的组合值,具体取决于指针的大小)是该值1作为指针值,并尝试访问表达式p[0][0]中地址1的内存.

then it will have undefined behavior because p[0] considers the value stored in the element a[0][0] (or the combined value stored in elements a[0][0] and a[0][1] depending on the size of the pointer) that is the value 1 as a pointer value and try to access the memory at address 1 in the expression p[0][0].

这篇关于C-指向指针数组的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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