3 回答
TA贡献1884条经验 获得超4个赞
不,该教程的质量值得怀疑。我不建议继续阅读它。
A char**是指针到指针。它不是二维数组。它不是指向数组的指针。它不是指向2D数组的指针。
本教程的作者可能会感到困惑,因为存在广泛的错误和错误做法,说您应该分配动态2D数组,如下所示:
// BAD! Do not do like this!
int** heap_fiasco;
heap_fiasco = malloc(X * sizeof(int*));
for(int x=0; x<X; x++)
{
heap_fiasco[x] = malloc(Y * sizeof(int));
}
但是,这不是2D数组,它是一个缓慢的,碎片化的查找表,分配给整个堆。访问查找表中一项的语法heap_fiasco[x][y]类似于数组索引语法,因此许多人出于某种原因认为这是分配2D数组的方式。
动态分配2D数组的正确方法是:
// correct
int (*array2d)[Y] = malloc(sizeof(int[X][Y]));
您可以说第一个不是数组,因为如果这样做memcpy(heap_fiasco, heap_fiasco2, sizeof(int[X][Y])),代码将崩溃并燃烧。这些项目未分配在相邻的存储器中。
同样memcpy(heap_fiasco, heap_fiasco2, sizeof(*heap_fiasco))也会崩溃和烧毁,但是由于其他原因:您得到的是指针的大小而不是数组的大小。
虽然memcpy(array2d, array2d_2, sizeof(*array2d))会起作用,因为它是2D数组。
TA贡献1866条经验 获得超5个赞
指针花了我一段时间来理解。我强烈建议绘制图表。
请阅读并理解C ++教程的这一部分(至少在指针方面,图表确实对我有所帮助)。
告诉您对于二维数组,您需要一个指向char的指针是一个谎言。您不需要它,但这是实现它的一种方法。
内存是顺序的。如果您想像单词hello那样连续放置5个字符(字母),则可以定义5个变量,并始终记住使用它们的顺序,但是如果要保存6个字母的单词会怎样呢?您是否定义更多变量?如果只按顺序将它们存储在内存中会不会更容易?
因此,您要做的就是向操作系统请求5个字符(每个字符恰好是一个字节),然后系统将向您返回一个内存地址,该地址开始您的5个字符的序列。您使用此地址并将其存储在变量中,我们将其称为指针,因为它指向您的内存。
指针的问题在于它们只是地址。您怎么知道该地址存储了什么?是5个字符还是8个字节的大二进制数字?还是它是您加载的文件的一部分?你怎么知道的?
这是像C这样的编程语言试图通过提供类型来帮助您的地方。类型告诉您变量存储的内容,而指针也具有类型,但是其类型告诉您指针指向的内容。因此,char *是指向存储位置的指针,该存储位置包含单个char或一系列chars。可悲char的是,您需要记住自己有关多少个数字的部分。通常,您将这些信息存储在一个变量中,以提醒您有多少个字符。
那么,当您想要拥有二维数据结构时,该如何表示呢?
最好用一个例子来解释。让我们做一个矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
它具有4列和3行。我们如何存储它?
好吧,我们可以制作3个序列,每个序列有4个数字。第一个序列为1 2 3 4,第二个序列为,5 6 7 8第三个和最后一个序列为9 10 11 12。因此,如果我们要存储4个数字,我们将要求系统为我们保留4个数字并为它们提供一个指针。这些将是指向数字的指针。但是,由于我们需要3个指针,因此我们将要求系统给3个指针指向指针编号。
这就是您最终得到建议的解决方案的方式...
另一种方法是认识到您需要4乘3的数字,然后要求系统按顺序存储12个数字。但是,您如何访问第2行和第3列中的数字?这是数学的用武之地,但让我们在示例中进行尝试:
1 2 3 4
5 6 7 8
9 10 11 12
如果我们将它们彼此相邻存储,它们将如下所示:
offset from start: 0 1 2 3 4 5 6 7 8 9 10 11
numbers in memory: [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]
所以我们的映射是这样的:
row | column | offset | value
1 | 1 | 0 | 1
1 | 2 | 1 | 2
1 | 3 | 2 | 3
1 | 4 | 3 | 4
2 | 1 | 4 | 5
2 | 2 | 5 | 6
2 | 3 | 6 | 7
2 | 4 | 7 | 8
3 | 1 | 8 | 9
3 | 2 | 9 | 10
3 | 3 | 10 | 11
3 | 4 | 11 | 12
现在,我们需要制定一个简单易行的公式,将行和列转换为偏移量……如果我有更多时间,我会回到它的位置上……现在我需要回家(抱歉)。 ..
编辑:我有点晚了,但让我继续。要查找行和列中每个数字的偏移量,可以使用以下公式:
offset = (row - 1) * 4 + (column - 1)
如果您注意到-1这里的两个数字,您会发现这是因为我们的行号和列号以1开头,所以我们必须这样做,这就是计算机科学家偏爱基于零的偏移量的原因(由于该公式) )。但是,对于C语言中的指针,当您使用多维数组时,语言本身会为您应用此公式。因此,这是另一种方式。
TA贡献1829条经验 获得超13个赞
从您的问题中,我了解的是您在问为什么要为声明为* names []的变量使用char **。因此,答案是当您只写names []时,它就是array的语法,而array本质上是一个指针。
因此,当您编写* names []时,这意味着您要指向一个数组。而且因为数组基本上是一个指针,所以这意味着您有一个指向指针的指针,这就是为什么如果您编写的话编译器不会抱怨的原因
char ** cur_name =名称;
在上面的代码行中,您声明了一个指向字符指针的指针,然后使用指向数组的指针初始化它(记住数组也是指针)。
- 3 回答
- 0 关注
- 311 浏览
添加回答
举报