当前位置: 首页 > 知识库问答 >
问题:

在C中使用**时的差异

卓正业
2023-03-14

我最近开始学习C,我在理解指针语法时遇到了问题,例如当我写以下行时:

int ** arr = NULL;

我怎样才能知道:

>

arr是指向整数指针数组的指针

arr是指向整数数组指针数组的指针

int**不都是一样的吗?

如果我有一个接收char**s作为参数的函数,我想将其称为指向字符串数组的指针,这意味着指向指向chars数组的指针数组的指针,但它也是指向char指针的指针吗?

共有3个答案

金嘉
2023-03-14

我如何知道:

  • arr是指向整数指针的指针

它始终是指向整数的指针。

  • arr是指向整数指针数组的指针

不可能是这样的。指向整数指针数组的指针的声明如下:

int* (*arr)[n]

听起来好像你被拙劣的老师/书籍/教程欺骗使用了int**。它几乎总是不正确的练习,正如这里和这里以及(关于数组指针的详细解释)这里所解释的。

编辑

终于抽出时间写了一篇详细的文章,解释什么是数组,什么是查找表,为什么后者不好,以及你应该使用什么:正确分配多维数组。

子车安和
2023-03-14

声明称:“将arr声明为指向整数指针的指针”。它(如果有效)指向一个指针,该指针(如果有效)指向一个整数对象。由于可以将指针算法与任一间接级别一起使用(即,*arrarr[0]相同,**arrarr[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]

实际上,数组指针最常用于将维度不变的多维数组传入函数,以及传入长度可变的数组。很少看到将变量声明为数组指针的语法,因为每当将变量传递到函数中时,使用类型为“array of undefined size”的参数会更容易,因此不必声明

void func(int (*a)[10]);

一个人可以用

void func(int a[][10])

传入一个由10个整数组成的多维数组。或者,可以使用typedef来减轻头痛。

尉迟高澹
2023-03-14

这和int**不都一样吗?

您刚刚发现了可能被认为是类型系统中的缺陷。您指定的每个选项都可能为真。它本质上来自程序内存的平面视图,其中单个地址可用于引用各种逻辑内存布局。

自C诞生以来,C程序员一直在处理这个问题,方法是制定一个约定。例如为接受此类指针的函数要求大小参数,并记录他们对内存布局的假设。或者要求数组以特殊值终止,从而允许指向缓冲区的指针的“锯齿”缓冲区。

我觉得需要做一些澄清。正如你在这里查阅其他非常好的答案时所看到的那样,数组绝对不是指针。然而,它们确实会在足够的上下文中衰减成一个数组,从而保证在教授它们时出现长达数十年的错误(但我离题了)。

我最初编写的代码如下:

void func(int **p_buff)
{
}

//...

int a = 0, *pa = &a;
func(&pa);

//...

int a[3][10];
int *a_pts[3] = { a[0], a[1], a[2] };
func(a_pts);

//...

int **a = malloc(10 * sizeof *a);
for(int i = 0; i < 10; ++i)
  a[i] = malloc(i * sizeof *a[i]);
func(a);

假设func并且每个代码片段都编译在一个单独的翻译单元中。每个示例(除非我有任何错别字)都是有效的C。数组在作为参数传递时将衰减为“指针到指针”。func定义如何仅从其参数的类型就知道它到底传递了什么!?答案是它不能。p_buff的静态类型是int**,但它仍然允许func间接访问(部分)有效类型大相径庭的对象。

 类似资料:
  • 本文向大家介绍C ++中的最小时差,包括了C ++中的最小时差的使用技巧和注意事项,需要的朋友参考一下 假设我们有一个“小时:分钟”格式的24小时制时钟点列表,我们必须找到列表中任何两个时间点之间的最小分钟差。因此,如果输入类似于[“ 12:30”,“ 15:17”],则返回167。 为了解决这个问题,我们将遵循以下步骤- 定义一个大小为24 * 60 + 1的名为ok的数组,并且最初都为假。 n

  • 问题内容: 我有两个几乎相似的MDX查询,其中一个是我使用.CHILDREN,另一个是.ALLMEMBERS。第一个不返回任何行,第二个不返回两个行。请帮助我理解原因! 查询1 -– 2行 查询2 -无行 -—索赔截至-计数-全部637,350 –2010 637,350 只是加起来,AccidentDate是我的多维数据集[AW Cube]中的维度之一。年份是自然层次结构,而[年份-季度-月-

  • 本文向大家介绍C++与C的差异分析,包括了C++与C的差异分析的使用技巧和注意事项,需要的朋友参考一下 虽说C++是向后兼容C的,但C++与C还是存在许多差异。本文列举了几个例子加以说明,同时这些也是我们非常容易忽略的地方。本文仅简单的列举几例,更多的不同之处读者还需要在学习与实践中不断的进行发掘和总结。 C编译通过但C++编译不通过: 1、C++中编译器不允许在一个函数声明之前调用它,但C中编译

  • 本文向大家介绍C ++中两个给定时间段之间的差异,包括了C ++中两个给定时间段之间的差异的使用技巧和注意事项,需要的朋友参考一下 问题陈述 以字符串'HH:MM:SS'格式给出两个时间段。在这里,“ HH”代表小时,“ MM”代表分钟,“ SS”代表秒。找到这两个时间段之间相同字符串格式的差异。 示例 以下是C ++中的程序,用于查找所需的输出。 输出结果

  • 问题内容: 编译并在C中运行此代码 输出: 现在对于Java中的相同逻辑 输出: 为什么两种语言的输出都不同,输出是可以理解的,但我无法理解 还有一件事,如果应用前缀运算符,那么两种语言的结果相同,为什么呢? 问题答案: 这是因为在C.看看所调用未定义行为这 从链接: 第二句说:如果将对象写入完整表达式中,则在同一表达式中对对象的任何和所有访问都必须直接参与要写入的值的计算。该规则有效地将法律表达

  • 本文向大家介绍C ++中子集差异的总和,包括了C ++中子集差异的总和的使用技巧和注意事项,需要的朋友参考一下 在这个问题上,我们得到了一个n的集合S。我们的任务是创建一个程序,以查找子集差异之和,即子集的最后一个元素与第一个元素的差异。 公式是 让我们举个例子来了解这个问题, 输入 - 输出- 说明-所有子集是- 解决该问题的简单方法是找到所有子集的last和first之间的差异,然后将它们相加