AKA - 指针为什么如此受关注?
我只用过像ActionScript,Java和C#这样的现代面向对象语言,我不太理解指针的重要性以及你如何使用它们。我在这方面错过了什么?
AKA - 指针为什么如此受关注?
我只用过像ActionScript,Java和C#这样的现代面向对象语言,我不太理解指针的重要性以及你如何使用它们。我在这方面错过了什么?
这一切只是间接的:能够不直接处理数据,而是说“我将指引你去那里的某些数据”。在Java和C#中有相同的概念,但只以引用格式存在。
关键区别在于引用实际上是不可变的路标——它们总是指向某些东西。这很有用,也很容易理解,但比C指针模型的灵活性要低。C指针是可以愉快地重写的路标。你知道你要查找的字符串就在被指向的字符串旁边吗?好吧,稍微改变一下路标。
这与C的“贴近底层、需要低级知识”的方法很搭配。我们知道char* foo
由从foo标志点开始的一组字符组成。如果我们还知道该字符串至少有10个字符长,我们可以将标志点更改为(foo+5)
,以指向同一字符串,但从一半处开始。
当你知道自己在做什么时,这种灵活性非常有用,但如果你不知道则会有致命后果(“知道”不仅仅是“知道语言”,还包括“确切了解程序的状态”)。弄错了,你的路标就会引领你走向悬崖边缘。引用不让你乱动,所以你更有信心在没有风险的情况下跟随它们(尤其是与规则相结合时,比如“被引用的对象永远不会消失”,这在大多数垃圾回收语言中都是这样的)。
你错过了很多!了解计算机的底层工作原理在许多情况下非常有用。C和汇编语言可以帮助你实现这一点。
基本上,指针让你将数据写入计算机内存中的任何位置。在更原始的硬件/操作系统或嵌入式系统中,这可能会做一些有用的事情。例如打开和关闭blinkenlichts(指灯)。
当然,在现代系统上这并不起作用。操作系统是主内存的主人和大师。如果尝试访问错误的内存位置,则进程将因其傲慢而付出生命的代价。
在C中,指针是传递数据引用的方式。当调用函数时,你不想将一百万个比特位复制到堆栈中。相反,你只需告诉在主内存中数据所在的位置即可。换句话说,你提供了一个指向该数据的指针。
在某种程度上,这也是Java中发生的事情。你传递对象的引用,而不是对象本身。请记住,最终每个对象都是计算机主内存中的一组比特位。
指针是用于直接操纵内存内容的。
你可以自行决定这是否是一件好事,但这是C或汇编中完成任何操作的基础。
高级语言将指针隐藏在幕后:例如,在几乎所有JVM中,Java中的引用都被实现为指针,这就是为什么它被称为NullPointerException而不是NullReferenceException的原因。但是,它不允许程序员直接访问它所指向的内存地址,并且不能被修改以取代正确类型对象的地址。因此,它没有提供与低级语言中指针相同的功能(和责任)。
[编辑:这是对问题“这种关注指针的痴迷是什么?”的回答。我所比较的只是汇编/C风格的指针和Java引用。由于问题标题已更改:如果我想回答新问题,我可能会提到除Java以外的其他语言中的引用]
这就像是问:“为什么对CPU指令如此痴迷?如果我不在程序中到处使用x86 MOV指令,会错过什么吗?”
只有在进行低级编程时才需要用到指针。在大多数高级编程语言的实现中,指针与在C语言中一样经常被使用,但却被编译器从用户中隐藏。
所以... 不要担心。你已经在使用指针了——而且没有出现使用不当的危险。 :)
如果您之前没有接触过指针,那么您一定会错过这个小宝石:
void strcpy(char *dest, char *src)
{
while(*dest++ = *src++);
}
字符串是C语言(以及其他相关语言)的基础。在使用C语言编程时,你必须管理自己的内存。你不能只说“好吧,我需要一堆字符串”;你需要考虑数据结构。你需要多少内存?什么时候分配它?什么时候释放它?假设你想要10个字符串,每个字符串不超过80个字符。
好的,每个字符串都是一个字符数组(81个字符 - 你不能忘记空值,否则你会后悔!),然后每个字符串本身又是一个数组。最终结果将是一个类似于多维数组的东西。
char dict[10][81];