在C语言中使用**时的差异
在C语言中使用**时的区别
在C语言中,使用**的方式有很多种,但是很多时候这种写法是错误的。这可能是因为我们受到了错误的教育或者书籍/教程的误导。下面将详细解释在C语言中使用**的一些常见问题以及解决方法。
首先,如果我们想要知道arr是一个指向整数的指针的指针,答案总是肯定的,它是一个指向指针的指针。然而,如果我们想要知道arr是一个指向整数指针数组的指针,或者是一个指向整数数组的指针数组的指针,这是不可能的。指向整数指针数组的指针应该声明为int* (*arr)[n]。
那么为什么会出现这种错误的写法呢?可能是因为我们受到了错误的教育或者书籍/教程的误导。事实上,使用int**几乎总是不正确的做法。这在这里和这里以及这里都有详细解释(包括有关数组指针的详细解释)。
如果我们想要使用malloc来分配一个指向整数指针数组的指针,那么应该这样写:
int* (*arr)[n] = malloc(sizeof(int*) * n);
这样可以正确地分配内存并将arr指向数组的首地址。
另外,如果我们将arr声明为一个指向整数指针数组的指针,那么函数的参数应该是void func(int (**arr)[n]),并且在调用函数时应该传递arr的地址,即func(&arr)。
总之,int**不能用来表示指向整数指针数组的指针,这是一个常见的错误。正确的写法是使用int* (*arr)[n]表示指向整数指针数组的指针。这种错误的写法可能是由于错误的教育或者书籍/教程的误导所致。希望通过这篇文章可以帮助大家正确理解在C语言中使用**的区别。
在C语言中,使用**的区别
在C语言中,声明int** arr
意味着"声明arr为指向整数的指针的指针"。如果有效,它指向一个指针,该指针指向一个整数对象。由于可以对任何一级的间接引用使用指针运算(即*arr
和arr[0]
是等价的,**arr
和arr[0][0]
是等价的),因此可以使用该对象来访问您问题中的任意3个对象(也就是说,对于第二个问题,访问指向整数的指针数组,对于第三个问题,访问指向整数数组的第一个元素的指针数组),前提是指针指向数组的第一个元素...
然而,arr
仍然被声明为指向单个指向单个整数对象的指针。还可以声明指向具有定义维度的数组的指针。在这里,a
被声明为指向10个元素的数组的指针,这些数组指向10个整数的数组:
cdecl> declare a as pointer to array 10 of pointer to array 10 of int; int (*(*a)[10])[10]
在实践中,数组指针最常用于将多维数组传递给函数,并传递可变长度的数组。很少见到将变量声明为指向数组的指针的语法,因为每当它们被传递给函数时,使用"未定义大小的数组"类型的参数会更容易一些,所以可以使用以下方式来代替声明:
void func(int (*a)[10]);
可以使用以下方式传递多维数组的数组:
void func(int a[][10])
另外,可以使用typedef
来减少编程的复杂性。
指向数组的指针并不是什么晦涩的概念。它们是传递多维数组的唯一方式。
好吧,那么也许指向数组的指针是晦涩的 😀
: 确实如此。对于绝大多数代码来说,这样复杂的结构表明接口设计有问题。一个原因是指针没有长度信息。在整个调用树中始终传递每个维度的长度是有问题的,因此人们会使用中间的struct
。对于"指向指针数组的指针",可以使用2D数组(所有"内部"数组的长度相等)或指向struct { length, pointer to data}
或指向struct
的指针。
在C语言中,使用**的区别主要体现在指针和数组之间的差异。这种差异可能导致代码中出现问题,但我们可以通过一些解决方法来解决这个问题。
C语言中的**表示指向指针的指针。**可以用于多种情况,但由于C语言的类型系统的限制,它可能会导致一些问题。C程序员通常通过制定一些约定来解决这个问题,比如在接受这种指针的函数中要求使用大小参数,并记录关于内存布局的假设,或者要求数组以特殊值结尾,从而允许使用指针缓冲区的“不规则”缓冲区。
在代码示例中,我们可以看到这个问题的具体表现。当将数组作为参数传递给函数时,数组会自动转换为指向指针的指针。然而,函数的定义无法仅通过参数的类型来确定它传递了什么。因此,**的静态类型是int**,但它仍然允许函数间接地访问具有不同有效类型的对象。
为了解决这个问题,我们需要明确指定参数的类型,并且在使用指针的时候要小心处理。此外,我们还可以使用特定的约定来确保代码的正确性。
总之,C语言中使用**时,指针和数组之间存在差异。这种差异可能导致代码中的问题,但我们可以通过明确指定类型和使用约定来解决这个问题。