简体   繁体   English

检查以下代码。 它与数组概念的指针有关

[英]Check the following code. Its related to the pointer to an array concept

Consider the following code 考虑以下代码

#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));
            }
    }
}

The code basically creates a 2-D array, then creates a pointer to 1-D array. 该代码基本上创建了一个二维数组,然后创建了一个指向一维数组的指针。 Then the pointer to the 1-D array is initialized with the code p = &s[i]; 然后,使用代码p =&s [i];初始化指向一维数组的指针。

The next line initializes a pointer to an integer 'pint'. 下一行初始化一个指向整数“品脱”的指针。 pint = (int *)p; 品脱=(int *)p;

I was wondering why the following line of code doesn't work. 我想知道为什么下面的代码行不起作用。 It makes logical sense. 这是合乎逻辑的。 pint = p; 品脱= p;

p is type int (*)[2] which is related to s and indeed any assignment pint (*)[2] ,与s以及任何赋值相关

p = s + (int)x;

will work. 将工作。 But pint is of type int * . 但是pintint *类型的。 Although you are casting p to that type you are pushing it for undefined behaviour. 尽管将p强制转换为该类型,但仍将其强制为未定义的行为。

What you probably want is 您可能想要的是

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));
        }
}

It will not compile. 它不会编译。

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

It should be 它应该是

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

See the working code here: http://ideone.com/CvNlxG 在此处查看工作代码: http : //ideone.com/CvNlxG

In C the value of an array is a pointer to its first element. 在C语言中,数组的值是指向其第一个元素的指针。 You have: 你有:

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

So let's look at the types in your expressions: 因此,让我们看一下表达式中的类型:

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

Left hand side, pointer to array of two ints, right hand side, exactly the same. 左侧,指向两个int数组的指针,右侧,完全相同。

        pint= (int *)p;

Right hand side is forcibly converted, no need to examine further. 右侧被强制转换,无需进一步检查。

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

pint is pointer to int, so pint+j points j ints past what pint points at, * that is an int. pint是指向int的指针,因此pint + j指向j int超出了pint所指向的位置,*即为int。

which all work, and you want 所有这些都可以,而且您想要

    pint = p;

which doesn't. 没有。 Left hand side is pointer to int, right hand side is pointer to array of two ints, see above. 左手边是指向int的指针,右手边是指向两个int的数组的指针,请参见上文。

So you can do 所以你可以做

    pint = *p;

or 要么

    pint = p[0];

which has exactly the same semantics -- in fact, p[j] is defined to be *(p+j) , which works, because of the array value semantics. 它具有完全相同的语义-实际上,由于数组值语义, p[j]定义*(p+j) ,它可以工作。

Or you could use the 或者您可以使用

    pint = &p[0];

construction I flagged above as a trap. 我在上面将其标记为陷阱。 It's the same as the previous expression, here , because of the rule, but it breaks an extremely commonly-used equivalence: 由于规则,它与以前的表达式在这里相同,但是它打破了一个极其常用的等价关系:

int *P = p[0]; 

works for all of the following declarations of p : 适用于p的以下所有声明:

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

but &p[0] doesn't, and the breakage is more likely than you might expect, C programmers simply expect that code built to work with fixed-size arrays also works with variable-sized ones just by changing declarations. 但是&p[0]不会,而且破损的可能性比您预期的要大,C程序员只是希望为固定大小的数组构建的代码也可以通过更改声明而与可变大小的数组一起使用。

p is of type int (*)[2] . pint (*)[2] pint is of type int* . pint类型为int*

They are two different types, which is why the statement pint = p; 它们是两种不同的类型,这就是为什么语句pint = p; will not work. 不管用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM