Skip to content

Instantly share code, notes, and snippets.

@0
Created December 20, 2013 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0/8061350 to your computer and use it in GitHub Desktop.
Save 0/8061350 to your computer and use it in GitHub Desktop.
Arrays aren't pointers!
/* gcc -std=c99 -pedantic -Wall -Wextra -Werror -o arrays_pointers arrays_pointers.c
*/
#include <stdio.h>
#include <string.h>
#define A_LEN 5
void foo(int a[], int *p);
int main() {
size_t n;
int a[] = {2, 3, 5, 7, 11};
int *p = NULL;
char *s = "H iahnpagpc!yk";
// Where are the variables a and p stored in memory?
printf("&a: %p\n", (void *)&a);
printf("&p: %p\n", (void *)&p);
printf("\n");
// Where do a and p "point"? a is not a pointer, so it doesn't /really/
// point anywhere, but we can still cast it to one.
printf("a: %p\n", (void *)a);
printf("p: %p\n", (void *)p);
printf("\n");
// How many bytes do these objects take up?
printf("sizeof a: %zu\n", sizeof a);
printf("sizeof p: %zu\n", sizeof p);
printf("sizeof *a: %zu\n", sizeof *a);
printf("sizeof *p: %zu\n", sizeof *p);
// No segfault! The index isn't actually used, as sizeof happens at compile
// time.
printf("sizeof a[1000]: %zu\n", sizeof a[1000]);
printf("sizeof p[1000]: %zu\n", sizeof p[1000]);
printf("\n");
// We *can* get the length of an array if it's known at compile time.
printf("A_LEN: %d\n", A_LEN);
printf("sizeof a / sizeof *a: %zu\n", sizeof a / sizeof *a);
printf("\n");
// sizeof also works on types.
printf("sizeof(int[A_LEN]) %zu\n", sizeof(int[A_LEN]));
printf("sizeof(int*): %zu\n", sizeof(int*));
printf("sizeof(int): %zu\n", sizeof(int));
printf("\n");
// We inspect the array initialized above, but we can't dereference p (p is
// a null pointer, so p[0] should segfault).
for (size_t i = 0; i < A_LEN; i++) {
printf("a[%zu]: %d\n", i, a[i]);
}
printf("\n");
foo(a, p);
printf("\n");
// Change the pointer to point to the array.
printf("p = a\n");
p = a;
printf("\n");
printf("&a: %p\n", (void *)&a);
printf("&p: %p\n", (void *)&p);
printf("\n");
printf("a: %p\n", (void *)a);
printf("p: %p\n", (void *)p);
printf("\n");
printf("sizeof a: %zu\n", sizeof a);
printf("sizeof p: %zu\n", sizeof p);
printf("\n");
for (size_t i = 0; i < A_LEN; i++) {
printf("a[%zu]: %d\n", i, a[i]);
printf("p[%zu]: %d\n", i, p[i]);
}
printf("\n");
// Array indexing is just syntactic sugar for pointer arithmetic. Note how
// it automagically accounts for the value of sizeof int and adds that each
// time 1 is added.
for (size_t i = 0; i < A_LEN; i++) {
printf("a + %zu: %p\n", i, (void *)(a + i));
printf("p + %zu: %p\n", i, (void *)(p + i));
printf("*(a + %zu): %d\n", i, *(a + i));
printf("*(p + %zu): %d\n", i, *(p + i));
}
printf("\n");
foo(a, p);
// There's really no reason to ever do this, but it works.
for (size_t i = 0; i < A_LEN; i++) {
printf("%zu[a]: %d\n", i, i[a]);
printf("%zu[p]: %d\n", i, i[p]);
}
printf("\n\n");
// Magic.
n = strlen(s);
for (size_t i = 0; i < n; i++) {
printf("%c", (3 * i % n)[s]);
}
printf("\n");
return 0;
}
void foo(int a[], int *p) {
printf(" Start foo.\n");
// These variables live at different addresses from those passed in (C has
// pass-by-value semantics).
printf("&a: %p\n", (void *)&a);
printf("&p: %p\n", (void *)&p);
printf("\n");
// But they still point to the same place. These are the values that have
// been passed in.
printf("a: %p\n", (void *)a);
printf("p: %p\n", (void *)p);
printf("\n");
// a has been collapsed to a pointer, because the compiler doesn't know
// anything about a in this function at compile time.
printf("sizeof a: %zu\n", sizeof a);
printf("sizeof p: %zu\n", sizeof p);
printf(" End foo.\n\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment