在C和C ++中,作为函数参数的int ** a和int a [] []之间的确切区别是什么?

Mihnea

我在编写带有矩阵的程序时遇到了这个问题,我曾经int** m声明过我的矩阵-因为我需要动态分配和使用的函数int a[][]我不记得有任何问题。但是当我使用一个简单的m[6][6]矩阵时,f(int**m, int** m2, rest params)我遇到了麻烦。

它编译了,当我运行程序(带有GCC的代码块)时,它刚刚崩溃了。我尝试通过添加printf()s进行调试if(),它在没有崩溃的块处崩溃。将第一个函数参数从修改int a[][]int* a[6]并继续运行,稍后修改了第二个参数,并且我的程序进行了第一次尝试。通过更仔细的调试,我可以保存int m[i][j]并检查是否为垃圾值,而不是我要放入的内容,这只是在放置10标记某些东西。

这些年来,除非我在执行此类操作时遇到GCC编译器错误,否则我将只写第一种想到的方法。

在所有4种组合中使用int**int [][]声明变量/获取函数参数的背后的逻辑是什么int**在函数头中使用的大多数预定义函数

我知道int [][]这不等于int**,它是int* []正确的,但是我想念的是什么?int[][]是一个多维数组,表示数组的数组,所有3种编写方式都相同。而且因为int[][]它几乎总是要求只让第一个参数为空,就像int array[][][][]我需要将int数组a[][n1][n2][n3]放入函数参数中,对吗?它需要知道除第一个数组之外的多维数组的维数,因为在声明函数参数时可以毫无问题地使用int*int[]

埃雷里卡

C和C ++之间int **a以及int a[][]作为函数参数的确切区别是什么

int *a这是一个指向int的指针。

int **a这是一个指向int的指针。

int a[]在所有其他上下文中,是未指定数量的int数组,但是作为函数参数声明符,它被调整为int的指针,在这种情况下,它与您编写的相同int *a

int a[][]是未指定数目的数组,未指定整数数目的数组,但是这种类型格式错误,因为array元素不能是未指定大小的数组。

int *a[]在所有其他上下文中,是未指定数量的int指针的数组,但是作为函数参数声明符,它被调整为指向int的指针,即在这种情况下,与您编写的相同int **a

int (*a)[N] 这是指向N个整数的数组的指针。

int a[][N]在所有其他上下文中,是未指定数量的N个int数组的数组,但是作为函数参数声明符,它被调整为指向N个int数组的指针,即在这种情况下,它与您编写的相同int (*a)[N]


一些例子:

void fun_1D(int*);        // argument is pointer to int
void fun_1D(int[]);       // same as above
void fun_1D(int[10]);     // same as above; note that 10 is ignored

int arr_1D[20];           // array of int
fun_1D(arr_1D);           // implicit conversion
fun_1D(&arr_1D[0]);       // same as above

void fun_2D(int (*)[20]); // note that 20 is not ignored
void fun_2D(int[][20]);   // same as above
void fun_2D(int[10][20]); // same as above; note that 10 is ignored

int arr_2D[20][20];       // array of array of int
fun_2D(arr_2D);           // implicit conversion
fun_2D(&arr_2D[0]);       // same as above

fun_1D(arr_2D[i]);        // implicit conversion
fun_1D(&arr_2D[i][0]);    // same as above

void fun_ptrs(int**);     // argument is pointer to pointer to int
void fun_ptrs(int*[]);    // same as above
void fun_ptrs(int*[10]);  // same as above; note that 10 is ignored

int *arr_ptr[20];         // array of pointers
fun_ptrs(arr_ptr);        // implicit conversion
fun_ptrs(&arr_ptr[0]);    // same as above

fun_1D(arr_ptr[i]);       // no conversion needed


// broken examples
fun_2D(arr_ptr);          // int*[20] is not int(*)[20]
fun_ptrs(arr_2D);         // int[20][20] is not int**

请注意,如何将声明为数组的函数参数调整为与左值到右值转换时数组将衰减到的指针类型相同的指针类型。

需要记住的一些简单经验法则:

  • 数组不是指针。
  • 指针不是数组。
  • 为数组的函数参数实际上不是数组。实际上,它被调整为指向该数组元素的指针。进行此调整后,函数参数永远不会是数组。除函数参数外,这不适用于任何其他上下文。
  • 并非每种类型都可以是数组的元素。未指定长度的数组就是这种类型。
  • 没有“数组未指定长度”类型的对象。它们只能用于引用其他地方定义的数组的外部变量声明中,或用于从数组的初始化程序推导出实际大小的定义中,或用于将数组调整为指向数组的指针的函数参数声明中。元素。

如果我在main中声明int a [6] [6]并调用需要int ** a的函数,那么它会起作用吗?

不,因为int[6][6]不是int**,它也不衰减为一。int[6][6]衰减到int(*)[6]如上所述。int(*)[6]并且int**不能互相转换。一个是指向数组的指针,另一个是指向指针的指针。

反过来

否,因为int[6][6]参数已调整为int(*)[6]为何不兼容,请参见上一段。

似乎int a[][]不被接受

正确。正如我在顶部的第四段中所解释的(不包括引号)。

如果我有函数f1(int * a)和f2(int a [])和f2(int a [6]),在这些情况下,sizeof(a)返回什么?

如上所述,所有这些都声明了type的参数int*sizeof a就是sizeof(int*)因为那是类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Common Lisp中的NULL和NIL之间的确切区别是什么?

来自分类Dev

Docker容器中SizeRootFs和SizeRw之间的确切区别是什么?

来自分类Dev

wpf中的ToolBarPanel和ToolBarTray之间的确切区别是什么?

来自分类Dev

nodejs 中的签名 cookie 和未签名 cookie 之间的确切区别是什么?

来自分类Dev

角度2:组件中私有属性和公共属性之间的确切区别是什么?

来自分类Dev

Django中的get_list_or_404和get_object_or_404之间的确切区别是什么?

来自分类Dev

read()和readline()的确切区别是什么?

来自分类Dev

client.dns.lookup选项中的“ use_all_dns_ips”和“ resolve_canonical_bootstrap_servers_only”之间的确切区别是什么?

来自分类Dev

Windows Azure和Windows IIS之间的确切区别是什么?

来自分类Dev

content-type:text / json和application / json之间的确切区别是什么?

来自分类Dev

适配器和代理模式之间的确切区别是什么?

来自分类Dev

“适配器”和“介体”模式之间的确切区别是什么?

来自分类Dev

拦截器和transformResponse之间的确切区别是什么?

来自分类Dev

“ ExpectedConditions.visibilityOfElementLocated”和“ ExpectedConditions.presenceOfElementLocated”之间的确切区别是什么?

来自分类Dev

线程入口和线程启动之间的确切区别是什么?

来自分类Dev

SessionLocaleResolver和FixedLocaleResolver之间的确切区别是什么

来自分类Dev

awk和grep cut之间的确切区别是什么?

来自分类Dev

$ mycol,[[mycol]]和[,mycol,with = FALSE]的地址列之间的确切区别是什么?

来自分类Dev

Linux内核发行版和版本之间的确切区别是什么?

来自分类Dev

“子shell”和“子进程”之间的确切区别是什么?

来自分类Dev

“终端”,“外壳”,“ tty”和“控制台”之间的确切区别是什么?

来自分类Dev

.login和.cshrc文件之间的确切区别是什么?

来自分类Dev

之间的确切区别是什么?。和 ?: 角度运算符

来自分类Dev

均值滤波器和中值滤波器之间的确切区别是什么

来自分类Dev

Windows-1252(1/3/4)和ISO-8859-1之间的确切区别是什么?

来自分类Dev

Windows-1252(1/3/4)和ISO-8859-1之间的确切区别是什么?

来自分类Dev

三元运算符和 && 运算符之间的确切区别是什么?

来自分类Dev

Charuco 马克笔和钻石马克笔之间的确切区别是什么?

来自分类常见问题

Docker EE(企业版),Docker CE(社区版)和Docker(自定义支持)之间的确切区别是什么?

Related 相关文章

  1. 1

    Common Lisp中的NULL和NIL之间的确切区别是什么?

  2. 2

    Docker容器中SizeRootFs和SizeRw之间的确切区别是什么?

  3. 3

    wpf中的ToolBarPanel和ToolBarTray之间的确切区别是什么?

  4. 4

    nodejs 中的签名 cookie 和未签名 cookie 之间的确切区别是什么?

  5. 5

    角度2:组件中私有属性和公共属性之间的确切区别是什么?

  6. 6

    Django中的get_list_or_404和get_object_or_404之间的确切区别是什么?

  7. 7

    read()和readline()的确切区别是什么?

  8. 8

    client.dns.lookup选项中的“ use_all_dns_ips”和“ resolve_canonical_bootstrap_servers_only”之间的确切区别是什么?

  9. 9

    Windows Azure和Windows IIS之间的确切区别是什么?

  10. 10

    content-type:text / json和application / json之间的确切区别是什么?

  11. 11

    适配器和代理模式之间的确切区别是什么?

  12. 12

    “适配器”和“介体”模式之间的确切区别是什么?

  13. 13

    拦截器和transformResponse之间的确切区别是什么?

  14. 14

    “ ExpectedConditions.visibilityOfElementLocated”和“ ExpectedConditions.presenceOfElementLocated”之间的确切区别是什么?

  15. 15

    线程入口和线程启动之间的确切区别是什么?

  16. 16

    SessionLocaleResolver和FixedLocaleResolver之间的确切区别是什么

  17. 17

    awk和grep cut之间的确切区别是什么?

  18. 18

    $ mycol,[[mycol]]和[,mycol,with = FALSE]的地址列之间的确切区别是什么?

  19. 19

    Linux内核发行版和版本之间的确切区别是什么?

  20. 20

    “子shell”和“子进程”之间的确切区别是什么?

  21. 21

    “终端”,“外壳”,“ tty”和“控制台”之间的确切区别是什么?

  22. 22

    .login和.cshrc文件之间的确切区别是什么?

  23. 23

    之间的确切区别是什么?。和 ?: 角度运算符

  24. 24

    均值滤波器和中值滤波器之间的确切区别是什么

  25. 25

    Windows-1252(1/3/4)和ISO-8859-1之间的确切区别是什么?

  26. 26

    Windows-1252(1/3/4)和ISO-8859-1之间的确切区别是什么?

  27. 27

    三元运算符和 && 运算符之间的确切区别是什么?

  28. 28

    Charuco 马克笔和钻石马克笔之间的确切区别是什么?

  29. 29

    Docker EE(企业版),Docker CE(社区版)和Docker(自定义支持)之间的确切区别是什么?

热门标签

归档