-10

While programming in python 3.6, I came across with some problem in list :

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

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

This code will obviously give an error :

IndexError: list index out of range

But in case of c language :

#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);
}

Gives the correct output(including garbage value):

2 3 4 5 32764

I wanted to know why are we not getting the value of elements of list in python by using the future values of n whereas in c it is just reverse?

BoRRis
  • 983
  • 8
  • 23
  • 4
    C doesn't care about the index of array, you can declare an array of length 5 and access the 6th element. It will however return you a garbage value for the 6th element. Python is strict and will return an `IndexError`. – Sagun Shrestha Dec 13 '17 at 11:03
  • Yes.But why the futures values of `n` being unable to give output in python? – BoRRis Dec 13 '17 at 11:04
  • 4
    @BoRRis simply because the language doesn't let you – Nick is tired Dec 13 '17 at 11:05
  • It looks like you need to pick up a book on exception handling in python. – cs95 Dec 13 '17 at 11:05
  • @Nick A this is what i want to know.Why and Whats happening behind the scene?In the memory level? – BoRRis Dec 13 '17 at 11:06
  • 3
    @BoRRis That's well outside the scope of this site, we're not here to explain how the underlying memory structures of C and Python work, I suggest you go and learn C and then read the Python source code – Nick is tired Dec 13 '17 at 11:08
  • 11
    Your C program is not "correct": it invokes undefined behavior and could just as well crash on access to `arr[5]`, or do some even worse thing. You're not guaranteed to get any value, even a garbage one. In Python you are guaranteed to get an `IndexError` instead. – Daniel Pryden Dec 13 '17 at 11:08
  • Why do you expect two different programming languages behave the same? – too honest for this site Dec 13 '17 at 19:47
  • 1
    @SagunShrestha: "C doesn't care about the index of array, you can declare an array of length 5 and access the 6th element." - **definitively not!** There is no 6th element. If you invoke undefined behaviour, you loose any warranty the language gives. – too honest for this site Dec 13 '17 at 19:48
  • @Olaf, I think it's clear that they mean access where the 6th element *would* be, more like the "6th" element – Nick is tired Dec 13 '17 at 22:01
  • @NickA: That is not guaranteed. And modern ABIs don't necessarily store such small arrays in RAM at all and the compiler might do what it wants. There is nothing useful trying to define **undefined behaviour**! By definition the array has 5 elements and assuming anything beyond that is extremely dangerous speculation. On a sidenote: such assumptions are the reason C has such a bad reputation for "crashing". – too honest for this site Dec 14 '17 at 00:53
  • @Olaf I'm not disputing that ^^, I'm merely suggesting what they were trying to comment – Nick is tired Dec 14 '17 at 00:55
  • @NickA: You missed the point of my comment. It was exactly to point out such assumptions are not just irrelevant, but very dangerous, expecially when stated to obvious beginners. (btw: there are [only 5 elements](https://www.youtube.com/watch?v=fQ9RqgcR24g)) – too honest for this site Dec 14 '17 at 00:57
  • @Olaf I'm not denying that, and I fully understood your comment, I repeat, I was merely suggesting what they were trying to comment, not agreeing with it – Nick is tired Dec 14 '17 at 01:00
  • On a sidenote: when iterating a list, use the ideomatic, _pythonic_ way with the list-iterator, not the C-ish way with indexing. That will also avoid the exception. – too honest for this site Dec 14 '17 at 12:59

1 Answers1

3

In C, an "array" is mainly a pointer to a memory location (nb: this is an obvious simplification, you can read this for more details), and arr[x] will return N bytes from address_of_arr + (N * x) (where N is the size of the array data type). Like all memory access in C, there's absolutely NO check so you can read (and write) just any arbitrary memory location.

Note that, as Daniel Pryden mentions in a comment, the behaviour you observe with your C example is called an "undefined behaviour", which means the result is not defined by the C langage specs, depends on the implementation (your C compiler, platform and whatnots), and could actually yield just any result (including a core dump, erasing your hard drive or launching a nuclear missile). Luckily the implementation you tested it with just returns garbage. Now if you really feel lucky, for a bit of fun try writing at this memory location and find out what happens ;)

In Python, a list is an object which knows it's length and won't let you try to access items at indexes that don't exist. Where and how the effective list contents are stored in memory is handled by the implementation and is totally opaque to the Python code.

Disclaimer : this answer is based on C implementations most commonly found on today's operating systems - the C language spec doesn't specify anything about how an array should be implemented (just how it's supposed to work) so an implementation could as well choose to store array datas on clay tablets disposed on a rubber band and move that rubber band by N positions left or right, in which case my answer would be totally irrelevant...

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118