【问题标题】:Lists in Python vs Arrays in C [closed]Python中的列表与C中的数组[关闭]
【发布时间】:2018-05-27 05:53:56
【问题描述】:

在 python 3.6 中编程时,我在list 中遇到了一些问题:

l = [2,2,3,3,3]

for n in range(len(l)):
   print(l[n+1])  #increasing value of n by 1

这段代码显然会报错:

IndexError: 列表索引超出范围

但如果是c 语言:

#include<stdio.h>

int main() {
int i =0;
int arr[5] = {1,2,3,4,5};
for(i = 0 ; i<=4;i++){

    printf("%d " , arr[i+1]);
}
return(0);
}

给出正确的输出(包括垃圾值):

2 3 4 5 32764

我想知道为什么我们不能通过使用n 的未来值在 python 中获取列表元素的值,而在 c 中它只是相反?

【问题讨论】:

  • C 不关心数组的索引,你可以声明一个长度为 5 的数组并访问第 6 个元素。但是,它会为您返回第 6 个元素的垃圾值。 Python 很严格,会返回一个IndexError
  • @BoRRis 只是因为语言不允许你
  • @BoRRis 这远远超出了本站的范围,我们不是来解释 C 和 Python 的底层内存结构是如何工作的,我建议你去学习 C 然后阅读 Python 源代码代码
  • 您的 C 程序不“正确”:它调用未定义的行为,并且在访问 arr[5] 时也可能崩溃,或者做一些更糟糕的事情。你不能保证得到任何价值,即使是垃圾。在 Python 中,您肯定会得到 IndexError
  • @SagunShrestha:“C 不关心数组的索引,你可以声明一个长度为 5 的数组并访问第 6 个元素。” - 绝对不是! 没有第 6 个元素。如果您调用未定义的行为,您将失去该语言提供的任何保证。

标签: python c arrays list


【解决方案1】:

在 C 中,“数组”主要是指向内存位置的指针(nb:这是一个明显的简化,you can read this for more details),arr[x] 将从 address_of_arr + (N * x) 返回 N 个字节(其中 N 是数组数据类型的大小)。与 C 中的所有内存访问一样,绝对没有检查,因此您可以读取(和写入)任意内存位置。

请注意,正如 Daniel Pryden 在评论中提到的那样,您在 C 示例中观察到的行为称为“未定义行为”,这意味着结果未由 C 语言规范定义,取决于实现(您的 C编译器、平台等等),并且实际上可能只产生任何结果(包括核心转储、擦除硬盘驱动器或发射核导弹)。幸运的是,您测试它的实现只是返回垃圾。现在,如果您真的感到幸运,可以尝试在这个内存位置并找出会发生什么;)

在 Python 中,list 是一个知道其长度的对象,并且不会让您尝试访问不存在索引处的项目。有效列表内容存储在内存中的位置和方式由实现处理,并且对 Python 代码完全不透明。

免责声明:这个答案是基于当今操作系统上最常见的 C 实现 - C 语言规范没有指定任何关于数组应该如何实现(只是它应该如何工作)的内容,所以一个实现也可以选择将数组数据存储在放置在橡皮筋上的粘土片上,并将橡皮筋向左或向右移动 N 个位置,在这种情况下,我的回答将完全无关紧要......

【讨论】:

  • 感谢积极响应。所以在 python 中它有所不同。
  • 而 arry 不是指针。甚至不要开始向初学者说出这种错误的说法!
  • 答案不正确。
  • @Olaf 是的,这确实是过于简单化了——我把它说得更清楚了,并添加了一个指向更详细解释的链接。
  • @BoRRis 很抱歉,尽管过于简单化(已更正),但答案仍然正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多