Created
December 20, 2013 20:50
-
-
Save 0/8061350 to your computer and use it in GitHub Desktop.
Arrays aren't pointers!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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