函数中* p和(* p)[3]之间有什么区别?

时间:2014-12-03 21:23:17

标签: c function pointers function-pointers memory-address

我是C语言编程和学习指针的新手。请看下面的程序。

第一个程序

  #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int **p)
   {
    *(*(p+1)+1)=2135;
    return 0;
     }

第二个计划

   #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int *p)
   {
    *((p+1)+1)=2135;
    return 0;
   }

第3个程序

     #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int (*p)[3])
   {
    *(*(p+1)+1)=2135;
    return 0;
     }
  1. 在第一个程序**p中使用fun()函数,我认为它应该是正确的,并且在该函数中,我已经编写*(*(p+1)+1)来更改第一个元素第一个数组。但在编制此程序时,它显示error: invalid type argument of unary '*' (have 'int')。据我所知,num是一个指向数组的指针,它保持num[1]的地址,该地址再次保持num[1][0]的地址。
  2. 编译第二个程序编译器时没有显示错误。而*((p+1)+1)=0正在改变第一个数组的第二个元素的值。为什么它改变第0个第2个元素的值而不是第一个数组的第一个元素的值?如何?它应该是*(*(p+1)+1)=0
  3. 在第三个程序中,编译器没有显示错误,并且显示正确的结果。怎么样?。 *(p)[3]是什么意思?
  4. 我搜索过这个但是无法找到满意的结果。

2 个答案:

答案 0 :(得分:1)

我想你在问:

之间有什么区别
int fun(int *p)

int fun(int (*p)[3])

第一个需要指向int的指针。第二个需要一个指向3 int s。

数组的指针

您可以使用num调用这两个函数,因为您将函数声明为

int fun();

如果声明函数已定义,则会出现第一个版本的编译器错误/警告。

以下是使用gcc和编译器标志-Wall的代码的更新版本以及生成的编译器警告。

#include <stdio.h>

int fun(int *p);

int main()
{
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   return 0;
}

int fun(int *p)
{
   *(p+0)=2135;
   return 0;
}
test.c: In function ‘main’:
test.c:7:4: warning: missing braces around initializer [-Wmissing-braces]
test.c:7:4: warning: (near initialization for ‘num[0]’) [-Wmissing-braces]
test.c:8:4: warning: passing argument 1 of ‘fun’ from incompatible pointer type [enabled by default]
test.c:3:5: note: expected ‘int *’ but argument is of type ‘int (*)[3]’

答案 1 :(得分:1)

您的所有程序都是格式错误的。您的编译器必须生成警告或错误消息,并且生成的任何可执行文件的输出都是无意义的。

它们格式不正确,因为int[3][3]int **int *int *[3]不兼容。

要将int[3][3]传递给某个函数,该函数必须接受int (*)[3]而不接受任何其他内容(嗯,void *除外)。

这是因为数组可以转换为指向数组第一个元素的指针。 (在C语法中,num可用于表示&num[0])。

在C中,只有真正的一维数组;类型为int[3][3]的数组被认为是一个包含3个元素的数组,每个元素都是3个整数的数组。

因此,指向num的第一个元素的指针是指向3个整数的数组的指针,该数组写为int (*p)[3]。你可以写:

int (*p)[3] = &num[0];

或同一事物的简写:

int (*p)[3] = num;

NB。你不断写*(*(num+1)+1))这是难以阅读的。而不是这个,num[1][1]似乎更清楚。

在C中,x[y]始终完全等同于*(x+y)