C *ptr[10]和(*ptr[10]之间的差异

C *ptr[10]和(*ptr[10]之间的差异,c,pointers,C,Pointers,对于以下代码: int (*ptr)[10]; int a[10]={99,1,2,3,4,5,6,7,8,9}; ptr=&a; printf("%d",(*ptr)[1]); 它应该打印什么?我在这里期望垃圾值,但输出是1 (我的结论是,以这种方式初始化指针数组,即ptr[10]将开始按顺序指向a[10]的元素) 但是这个代码片段呢: int *ptr[10]; int a[10]={0,1,2,3,4,5,6,7,8,9}; *ptr=a; pri

对于以下代码:

    int (*ptr)[10];
    int a[10]={99,1,2,3,4,5,6,7,8,9};
    ptr=&a;
    printf("%d",(*ptr)[1]);
它应该打印什么?我在这里期望垃圾值,但输出是
1

(我的结论是,以这种方式初始化指针数组,即
ptr[10]
将开始按顺序指向
a[10]
的元素)

但是这个代码片段呢:

int *ptr[10];
int a[10]={0,1,2,3,4,5,6,7,8,9};
*ptr=a;
printf("%d",*ptr[1]);

它给出了分段错误。

int*ptr[10]

这是一个由10个
int*
指针组成的数组,而不是像您假设的那样,一个指向10个
int
s数组的指针

int(*ptr)[10]

这是指向10
int

我相信这和
int*ptr一样
,两者都可以指向一个数组,但给定的表单只能指向一个包含10个
int
s

int(*)[10]
是指向一个包含10个成员的int数组的指针。i、 e它指向
inta[10]

其中as
int*[10]
是整数指针数组

#include <stdio.h>
int main()
{

int *ptr[10];
int a[10]={0,1,2,3,4,5,6,7,8,9};

printf("\n%p  %p", ptr[0], a);

*ptr=a; //ptr[0] is assigned with address of array a.

printf("\n%p  %p", ptr[0], a); //gives you same address

printf("\n%d",*ptr[0]); //Prints zero. If *ptr[1] is given then *(ptr + 1) i.e ptr[1] is considered which is uninitialized one.

return 0;
}
#包括
int main()
{
int*ptr[10];
inta[10]={0,1,2,3,4,5,6,7,8,9};
printf(“\n%p%p”,ptr[0],a);
*ptr=a;//ptr[0]被分配了数组a的地址。
printf(“\n%p%p”,ptr[0],a);//提供相同的地址
printf(“\n%d”,*ptr[0]);//打印为零。如果给出了*ptr[1],则认为*(ptr+1),即ptr[1]是未初始化的。
返回0;
}
int(*p)[10]表示p现在是指向大小为10的整数数组的指针

int*p[10]表示p是由10个整数指针组成的数组

int (*ptr)[10];
是指向10整数数组的指针

int *ptr[10];
是一个由10个指针组成的数组

故障原因:

*ptr=a; printf(“%d”,*ptr[1])

这里您将数组
a
的地址分配给
ptr
,它将指向元素
a[0]
。这相当于:
*ptr=&a[0]

但是,当您打印时,您可以访问
ptr[1]
,这是一个未初始化的指针,它是未定义的行为,因此给出segfault。

int(*p)[10]
是指向每行10个整数数组的指针,即可以有任意数量的行。基本上,它可以用来指向二维数组,并且可以通过增加
*(p+i)[10]
i
来访问维度,这与
a[i][10]
相同,这里
'i=1,2,3…
访问
1,2,3。。行

其中,
int*p[10]
是由10个整数指针组成的数组

如果数组是二维的,例如

b[2][10]={0,1,2,3,4,5,6,7,8,9},{10,11,12,13,14,15,16,17,18,19}
基本上,
(*ptr)[10]//如果省略了较高的维度索引,即2
可以用作指向数组(每行包含10个元素,即第一维度)的二维指针,如
(*ptr)[10]=&b
。 在
printf(“%d”)中,(*ptr)[1])(*ptr)
*(ptr+0)
计算为第一个维度,即
b[0][0]
的值为0。与wise一样,要访问数组的第二维
b[1][0]
表达式将是
**(ptr+1)
*(ptr+1)[0]
*(*(ptr+i)+j);
//其中i=1和j=0给出了第二维度的第一个元素,即10


我已经回答了很长时间,以便更容易理解。

对于
(*ptr)[10]
,只有两个用例:

  • 使用二维阵列时
  • typedef固定长度数组
由于上述Sree harsha Punyasamudram已经解释了第一个案例, 我将解释更奇特的用例

    #include <stdio.h>

typedef int arr1d10[10];
typedef int arr2d3[3][3];

void test1d0(arr1d10 *arr)
{
    /* This is the same as the case with function test1d1(). */
    printf("Element: %d\n", (*arr)[0]);
}

void test1d1(int (*arr)[10])
{
    /* As arr is a pointer to an array of 10 integers, pointer arithmetic will work with the size of an array of 10 integers, i.e. 
       when you increment arr it will increment by sizeof(arr1d10), which is 40 bytes.
       That's why when you dereference it, you can't simply do arr[1], because it will increment arr by 40 bytes forward.
       Also when dereferencing it, because it thinks it points to a whole array it will give you that array - it's address.
       This is another reason you can't do just arr[i], because those will be just addresses.
       The correct way is to dereference it once(*arr)), to get the address (think of implicitely casting to int*) and then you can do as usually (*arr)[1]).
    */
    printf("Element: %d\n", (*arr)[1]);
}

void test2d0(arr2d3 *arr2d)
{
    /* This is a little more complicated, but the principle is the same as above. */
    printf("Element: %d\n", (*arr2d)[0][0]);
}

void test2d1(int (*arr2d)[3][3])
{
    printf("Element: %d\n", (*arr2d)[0][1]);
}

int main(void)
{
    arr1d10 arr1d = {0, 1, 2};
    arr2d3 arr2d = { {0,1},{2,3},{3,4}};
    int (*p1d)[10] = &arr1d; 
    int (*p2d)[3][3] = &arr2d;

    printf("********** PRINT 1D array **********\n");
    test1d0(&arr1d);
    test1d1(&arr1d);
    test1d0(p1d);
    test1d1(p1d);

    printf("********** PRINT 2D array **********\n");
    test2d0(&arr2d);
    test2d1(&arr2d);
    test2d0(p2d);
    test2d1(p2d);

    return 0;
}
#包括
typedef int arr1d10[10];
typedef int arr2d3[3][3];
无效测试1d0(arr1d10*arr)
{
/*这与函数test1d1()的情况相同*/
printf(“元素:%d\n”,(*arr)[0]);
}
无效test1d1(int(*arr)[10])
{
/*由于arr是指向10个整数数组的指针,指针算法将与10个整数数组的大小一起工作,即。
当您增加arr时,它将增加sizeof(arr1d10),即40字节。
这就是为什么在取消引用它时,不能简单地执行arr[1],因为它会将arr向前增加40字节。
另外,当取消对它的引用时,因为它认为它指向一个完整的数组,所以它会给你这个数组——它的地址。
这是不能只执行arr[i]的另一个原因,因为这些只是地址。
正确的方法是将其解引用一次(*arr)),以获取地址(考虑隐式转换为int*),然后您可以像往常一样执行(*arr)[1])。
*/
printf(“元素:%d\n”,(*arr)[1]);
}
无效测试2D0(arr2d3*arr2d)
{
/*这有点复杂,但原理与上面相同*/
printf(“元素:%d\n”,(*arr2d)[0][0]);
}
void test2d1(int(*arr2d)[3][3])
{
printf(“元素:%d\n”,(*arr2d)[0][1]);
}
内部主(空)
{
arr1d10 arr1d={0,1,2};
arr2d3-arr2d={0,1},{2,3},{3,4};
int(*p1d)[10]=&arr1d;
int(*p2d)[3][3]=&arr2d;
printf(“*********打印1D数组************\n”);
test1d0(&arr1d);
test1d1(&arr1d);
test1d0(p1d);
test1d1(p1d);
printf(“**********打印二维数组************\n”);
test2d0(&arr2d);
test2d1(&arr2d);
test2d0(p2d);
test2d1(p2d);
返回0;
}

完全写“介于”和“输出”有那么难吗?@Eregrith:我会记住的…@GrijeshChauhan:谢谢。。!!