-1

I am switching from Python to C code for the purpose of my project. As I try to manipulate an array, it is very different from what I used to do in python. So I just want to know some "equivalent" operations for an array in C and Python.

So for numpy array in Python, we can directly sum(or other operations) up two arrays elementwise easily. In a sense, I think numpy array is like a virtual "matrix" that you can manipulate with as if it is stored as a whole(at least appear to).

For C array, it looks like a different animal. From what I could search out from the internet, I have to use for loop in order to do these basic operations. I think an array in C is just a set of values that are stored in addresses next to each other in order.

I know that C is much faster than Python, but I also know for loop is a nasty thing that should be avoided as possible in Python. Isn't these for loops in C slow the program down?(though I think when I use numpy module in Python, the module takes care of these for loops implicitly)

I also get a confusion about pointer. Consider this function that takes in a 1D array:

int myfunc(int *myarray);
{
 int sum=0;
 for(int i=0; i<sizeof(myarray); i++)
   {
     sum += myarray[i];
   }
 return sum
 }

Suppose I input some array say "arr", then I let:

*myarray = arr

Thus, later in the function when I am calling lines such as:

sum += myarray[i]

I am actually doing this:

sum += &arr

Which is really confusing. For me, it looks like I am directly adding addresses of variables with values of other variables. Is this code wrong or I misunderstand pointer?

Joe Xu
  • 27
  • 1
  • 4
  • 4
    Why don't you read a C book ? – Stargateur Jun 17 '17 at 19:49
  • @Stargateur I did read some articles but wasn't too helpful. And I need to write a C script real quick. – Joe Xu Jun 17 '17 at 19:57
  • 1
    @JoeXu C is not a scripting languages, and not a one you can write in after "some articles". – Uriel Jun 17 '17 at 19:58
  • @Uriel Well they are some articles about pointer. It is new concept to me so I am confused right now. – Joe Xu Jun 17 '17 at 20:06
  • 1
    `numpy` operations are fast **because** they use compiled C code to do the looping on primitive arrays. – juanpa.arrivillaga Jun 17 '17 at 20:09
  • 1
  • @juanpa.arrivillaga thanks! So when I am using numpy, it does these dirty loops for me. Whereas when I am writing in C, I have to do it myself right? – Joe Xu Jun 17 '17 at 20:13
  • @IljaEverilä I see... The sizeof() gives the size of the variable rather than the shape of array. – Joe Xu Jun 17 '17 at 20:14
  • @WeatherVane Thank you! Does that mean there is no native function in C that can read the shape of an array? – Joe Xu Jun 17 '17 at 20:15
  • @JoeXu you can't avoid loops. Looping over `numpy` arrays is particularly slow, because when you access the elements in that array you essentially have to do a boxing operation, unless you are working with an `dtype=object` array, but at that point, you might as well work with a Python `list`, because and object array is basically a bad Python `list` – juanpa.arrivillaga Jun 17 '17 at 20:16
  • @juanpa.arrivillaga Can I say that when I am looping over a C array(in C), it is cleaner than looping over a numpy array(in Python)? And this causes the huge difference in speed? – Joe Xu Jun 17 '17 at 20:19
  • @JoeXu No, there isn't. Arrays don't have a *shape*. Everything is C is much, much closer to the metal than Python, and there is much less abstraction than a `numpy` array. A C array is basically an evenly spaced chunk of memory. Check out the discussion in [this](https://stackoverflow.com/questions/17226278/pointers-and-arrays-learn-c-the-hard-way) question. – juanpa.arrivillaga Jun 17 '17 at 20:20
  • You can find the number of elements in an array with `sizeof array / sizeof array [0]`. But that will not work with a pointer, you must either provide the number of elements, or a sentinel (such as the `'\0'` terminator for a C "string"). But, there is rarely a need to establish number of elements either for static variables or dynamic ones, because you *provided that data at the point of definition, or memory allocation* and so is **already known**. – Weather Vane Jun 17 '17 at 20:25

1 Answers1

2

In your function:

int myfunc(int *myarray);             //  The ; at the end of this line will
                                      //  generate a compiler error.
{
 int sum=0;
 for(int i=0; i<sizeof(myarray); i++) // size of int* is the size of a pointer
                                      // 4 for 32bit app, or 8 for 64 bits apps
 {
     sum += myarray[i];
 }
 return sum
}

You should pass the number of elements to your array as a parameter for it to work:

int myfunc(int *myarray, int count)
{
 int sum=0;
 for (int i = 0; i < count; i++)                                           
 {
     sum += myarray[i];
 }
 return sum;
}

[Edit] When you do this:

sum += &arr;

You are incrementing sum with the address of variable arr.

Whereas:

sum += array[i];

increments sum with the int value stored at the (i+1)th position of array.

The following statement:

*myarray = arr;

Stores the value of arr into the value pointed to by myarray, this is equivalent to writing:

myarray[0] = arr;
Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • thx! But still, I don't quite understand "sum += myarray[i];" It feels like doing operations on addresses. Or, adding values with addresses – Joe Xu Jun 17 '17 at 20:03
  • It's equivalent to `sum = sum + myarray[i];` the `[ì]` index references a specific value in the array. – Michaël Roy Jun 17 '17 at 20:04
  • Yeah these are the same as in Python. What confuses me is that when I input an array in this function, I let *myarray = arr. So in the function, "myarray" would be the address of "arr" as far as I know. In this line, it looks like I am doing something like "0 + &arr". – Joe Xu Jun 17 '17 at 20:10
  • The main difference with python is that C arrays do not carry any information about their number of elements with them. Hence the extra parameter in the function. – Michaël Roy Jun 17 '17 at 20:18
  • I see what you mean. I've updated the answer to clarify what these very different statements do. – Michaël Roy Jun 17 '17 at 20:25
  • `*myarray = arr.` stores the contents of `arr` (an address if `arr` is an `int*`) into the first element of `myarray` – Michaël Roy Jun 17 '17 at 21:13