1

考虑以下代码

#include<stdio.h>
void main()
{
    int s[4][2] = 
    {  
        {20,1}, 
        {21,2}, 
        {22,3}, 
        {23,5}  
    };    
    int (*p)[2];
    int i,j,*pint;

    for( i=0;i<=3;i++)
    {
        p=&s[i];
        pint= (int *)p;

            for(j=0;j<=1;j++)
            { 
                printf("%d \n", *(pint + j));
            }
    }
}

该代码基本上创建一个二维数组,然后创建一个指向一维数组的指针。然后用代码 p = &s[i]; 初始化指向一维数组的指针。

下一行初始化一个指向整数“品脱”的指针。品脱 = (int *)p;

我想知道为什么下面的代码行不起作用。这是合乎逻辑的。品脱 = p;

4

4 回答 4

1

p是与任何赋值int (*)[2]相关的类型s

p = s + (int)x;

将工作。但pint属于类型int *。尽管您正在转换p为该类型,但您正在推动它以实现未定义的行为。

你可能想要的是

int i,j,*pint;

for( i=0;i<=3;i++)
{
    pint = s[i]; // pint points to the two ints in row i

        for(j=0;j<=1;j++) // i assume you missed the one here
        { 
            printf("%d \n", *(pint + j));
        }
}
于 2013-12-17T15:29:32.703 回答
0

在 C 中,数组的值是指向其第一个元素的指针。你有:

    int s[4][2];
    int (*p)[2];
    int i,j,*pint;

因此,让我们看看表达式中的类型:

        p=&s[i]; /* & here is unsafe, it's a trap, see at end. */

左侧,指向两个整数数组的指针,右侧,完全相同。

        pint= (int *)p;

右手边是强制转换的,不用再检查了。

                printf("%d \n", *(pint + j));

pint 是指向 int 的指针,因此 pint+j 将 j 个 int 指向 pint 所指向的位置,* 是一个 int。

这一切都有效,你想要

    pint = p;

没有。左侧是指向 int 的指针,右侧是指向两个 int 数组的指针,见上文。

所以你可以做

    pint = *p;

或者

    pint = p[0];

它具有完全相同的语义——实际上,由于数组值语义,它p[j]定义为有效。*(p+j)

或者你可以使用

    pint = &p[0];

我在上面标记为陷阱的构造。由于规则的原因,它与前面的表达式here相同,但它破坏了一个非常常用的等价:

int *P = p[0]; 

适用于以下所有声明p

int p[1][1];
int (*p)[1];
int **p;

&p[0]事实并非如此,而且损坏的可能性比您预期的要大,C 程序员只是希望构建用于固定大小数组的代码也可以通过更改声明来处理可变大小的数组。

于 2013-12-19T03:25:03.690 回答
0

它不会编译。

 for(j=0;j<=;j++)
            ^Missing the limit   

它应该是

 for(j=0;j < 2;j++)  

在此处查看工作代码:http: //ideone.com/CvNlxG

于 2013-12-17T15:20:35.167 回答
-3

p是类型int (*)[2]pint是类型int*

它们是两种不同的类型,这就是该语句pint = p;不起作用的原因。

于 2013-12-17T15:24:03.067 回答