开发者

Why does adding to a pointer pointed to the first array member cycle through them in C?

I've just read this that by pointing a pointer to the first array member, you can cycle through by adding to the pointer.

char my_array[] = "I am an array of chars";

char *my_pointer = my_array;

printf("%c\n", *my_pointer);

my_pointer++;

printf("%c", *my_pointer);

I guess this implies array members are always stored sequentially, and the space allocated is always reserved and an array's size can not be extended (because after the length it may contain other things in memory)?

Why does this work exactly? When accessing an array using a subscript, like my_array[5], will C only know where the array starts (i.e. my_array[0]), and have to increase an internal pointer by 5 to return it?

I apologize if this seems obvious, but I've spent my life in high le开发者_Go百科vel languages and C is very interesting to me.


Putting aside the problems with your code, yes, arrays are contiguous elements.

What happens with the second line of the code snippet below:

int * iptr = malloc (40 * sizeof(int));
int x = iptr[10];

is thus:

  • the value 10 is multiplied by the size of the int to get 70 (in this example, we assume a 7-byte int).
  • this is then added to the base pointer iptr (unscaled) and the (7-byte) value is extracted from that location.

This scaling is an important feature. You won't see it when you're working with char arrays but the values &(iptr[0]) and &(iptr[1]) will be separated by the size of an int, not a char (7 in our example case above).

When you add 1 to a pointer, that doesn't actually add 1, it adds the size of the underlying data type. So that:

int *p = &(iptr[0]);
p++;

won't give you an address corresponding to the second byte of that memory, it will actually give you the address of the second int (the seventh byte).

To that end, iptr[3] is exactly equivalent to *(i+3) in that they both give you element number three, even though it's made up of bytes from offset 21 through 27 inclusive.


Pre-emptive strike, just in case: keep in mind that a byte in ISO C is not necessarily 8 bits. ISO uses the term octet for that. A byte is the size of a char.


This nice answer might help


Your code has some bugs in it. Here is a working example.

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
  char my_array[] = "I am an array of chars";
  char* my_pointer = &my_array[0];

  int len = strlen(my_array);
  int i;
  for (i = 0; i < len; ++i) {
    printf("%c\n", *my_pointer);
    ++my_pointer;
  }

  return 0;
}

Like @RC's link points out, incrementing a pointer will walk the contiguous block of memory that is a C array.

If you change this line

char* my_pointer = &my_array[0];

to this

int* my_pointer = &my_array[0];

then not only will you get a compile warning, but you will get all kinds of gobbley-gook printed out as it will walk past the end of your array and print out whatever is in memory. Your pointer datatype should match your array if you want to walk over it properly.


I'm sorry, but there are a few mistakes in your example provided.

You need to declare my_array as

char my_array[] = "string...";

and get rid of either the & or the [0] in the second line (both have same effect).

you need to change the * in the 3rd and 5th lines to a & or a [0] (again, same effect).

The reason that this happens is because a string (array of char's) is a series of chars in memory. The char* points to the first one, so incrementing it will make it point to the second, third, ect...

You could increment it past the end of the string to see what else is stored in your app's memory (but this could crash your program).

-Alex


my_pointer point to a string in memory. Each CHAR is 1 byte. So my_pointer++ will look at the next byte and hence the next character. The read my_pointer++ as a string it will continue through memory until it finds null as all strings should be null terminated.

fyi

my_pointer += sizeof(type_of_array) will go to the next item in the array so long as you cast the pointer correctly.

malloc can be used to manage the memory available to your program. This takes care of finding free memory space to allocate the object to.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜