为什么指针是许多刚开始学习C或c++,甚至上了大学的学生困惑的主要因素?有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?

有什么好的实践可以让人达到“啊哈,我懂了”的水平,而不会让他们陷入整体概念中?基本上,就是模拟场景。


当前回答

通过迭代器来掌握它是个不错的方法。但继续看,你会发现亚历山大开始抱怨他们。

许多前c++开发人员(在抛弃语言之前从未理解迭代器是一个现代指针)跳转到c#,仍然相信他们有不错的迭代器。

嗯,问题是所有迭代器都与运行时平台(Java/CLR)试图实现的目标完全不一致:新的、简单的、人人都是dev的用法。这可能是好事,但他们在紫书里说过一次,甚至在C之前说过

间接。

这是一个非常强大的概念,但如果你一直这样做,就不会如此了。迭代器很有用,因为它们有助于算法的抽象,这是另一个例子。编译时是算法的地方,非常简单。你知道代码+数据,或者用其他语言c#:

IEnumerable + LINQ + Massive Framework = 300MB运行时惩罚间接的糟糕,拖动应用程序通过引用类型的实例堆..

“Le Pointer很便宜。”

其他回答

我不认为指针本身令人困惑。大多数人都能理解这个概念。现在你能想到多少个指针或者你能适应多少个间接层次。不需要太多就能让人崩溃。它们可能会被程序中的错误意外更改,这也会使它们在代码中出错时很难调试。

每个C/ c++初学者都有同样的问题,出现这个问题不是因为“指针很难学”,而是因为“解释指针的人以及如何解释”。有的学习者从口头或视觉上理解它,最好的解释方法是用“训练”样例(适用于口头和视觉样例)。

其中“火车头”是一个指针,它不能容纳任何东西,“马车”是“火车头”试图拉(或指向)的东西。之后,你可以对“马车”本身进行分类,它可以容纳动物、植物或人(或它们的混合)。

邮政信箱号码。

它是一条信息,允许你访问其他东西。

(如果你计算邮政信箱号码,你可能会有问题,因为信进了错误的信箱。如果有人搬到另一个州——没有转发地址——你就有一个悬浮指针。另一方面,如果邮局转发邮件,那么你就有了指向指针的指针。)

我喜欢用数组和下标来解释它——人们可能不熟悉指针,但他们通常都知道下标是什么。

所以我说,假设RAM是一个数组(你只有10个字节的RAM):

unsigned char RAM[10] = { 10, 14, 4, 3, 2, 1, 20, 19, 50, 9 };

然后,指向变量的指针实际上只是该变量在RAM中的第一个字节的索引。

因此,如果你有一个指针/索引unsigned char index = 2,那么这个值显然是第三个元素,或者数字4。指针指向指针的指针是指将该数字本身用作索引,如RAM[RAM[index]]。

我会在纸上的列表上画一个数组,然后用它来显示一些东西,比如指向同一个内存的许多指针、指针算术、指针到指针等等。

在C/ c++语言中,指针为什么是许多新、甚至老大学生困惑的主要因素?

一个值的占位符的概念——变量——映射到我们在学校教的东西——代数。如果不理解内存在计算机中是如何物理布局的,就无法画出一个现有的并行图,而且没有人会考虑这种事情,直到他们处理低级别的事情——在C/ c++ /字节通信级别。

有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?

地址框。我记得当我学习在微型计算机上编程BASIC时,有一些漂亮的书,里面有游戏,有时你必须在特定的地址中插入值。他们有一张图片,上面有一堆盒子,标有0、1、2……它解释说,只有一个小的东西(一个字节)可以装在这些盒子里,而它们有很多——一些计算机有多达65535!他们紧挨着,都有一个地址。

有什么好的实践可以让人达到“啊哈,我懂了”的水平,而不会让他们陷入整体概念中?基本上,就是模拟场景。

为了演习?创建一个结构体:

struct {
char a;
char b;
char c;
char d;
} mystruct;
mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;
cout << 'Start: my_pointer = ' << *my_pointer << endl;
my_pointer++;
cout << 'After: my_pointer = ' << *my_pointer << endl;
my_pointer = &mystruct.a;
cout << 'Then: my_pointer = ' << *my_pointer << endl;
my_pointer = my_pointer + 3;
cout << 'End: my_pointer = ' << *my_pointer << endl;

与上面的例子相同,除了在C中:

// Same example as above, except in C:
struct {
    char a;
    char b;
    char c;
    char d;
} mystruct;

mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;

printf("Start: my_pointer = %c\n", *my_pointer);
my_pointer++;
printf("After: my_pointer = %c\n", *my_pointer);
my_pointer = &mystruct.a;
printf("Then: my_pointer = %c\n", *my_pointer);
my_pointer = my_pointer + 3;
printf("End: my_pointer = %c\n", *my_pointer);

输出:

Start: my_pointer = s
After: my_pointer = t
Then: my_pointer = r
End: my_pointer = u

也许这通过例子解释了一些基础知识?