Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save najashark/b00c576684053db874aad61f581bd7c2 to your computer and use it in GitHub Desktop.
Save najashark/b00c576684053db874aad61f581bd7c2 to your computer and use it in GitHub Desktop.
https://www.andrew.cmu.edu/user/mteh/docs/C_Pointers.txt
Pointers
=====================================================================
---------------------------------------------------------------------
Reading C type declarations
---------------------------------------------------------------------
void * foo; (foo is a pointer to void; generic pointer)
char * foo; (foo is a pointer to char)
long **foo[7]; (foo is an array of 7 pointer to pointer to long)
1. start with var name (e.g. foo is ... )
2. end with basic type (e.g. foo is ... int)
3. filling in: ``go right when you can, go left when you must''
defs:
* means ``pointer to''
[] means ``array of''
() means ``function returning''
ref: http://unixwiz.net/techtips/reading-cdecl.html
Example from K&R:
int (*comp)(void *, void *);
// comp is a pointer to a funct (that has two void * arguments) returning int
int *comp(void *, void *);
// comp is a funct (that has two void * arguments) returning a pointer to int
=====================================================================
---------------------------------------------------------------------
Example (from K&R):
---------------------------------------------------------------------
int *p; // p is a pointer to int
int *x;
p = &c; // p stores the address of c
// p is said to ``point to'' c
p = c; // p stores the address `c'
// p points to whatever is at the address `c'
p = *x; // p stores the address ``int, which x points to''.
* is the _indirection_ or _dereferencing_ _operator_
when applied to a pointer, it accesses the obj the pointer points to.
&x produces the mem address where x is stored.
& is the address-of operator
int x = 1, y = 2, z[10];
int *p; // p is pointer to int
p = &x; // p now points to x
y = *p; // retrieves value of `int x' which is 1. Hence, y is now 1.
*p = 0; // assign 0 to the object that p pointers to. Hence, x is now 0.
p = &z[0]; // p now points to z[0]
p = z; // p now points to z[0]
p = &z; //invalid since `z' is an array
strcpy(dest, source) always slap a terminating null char (ascii 0) to the str.
// length is _determined_ by terminating null char;
// strlen excludes the null terminating char
hence, dest = malloc(strlen(source) + 1);
sizeof(void) // is _illegal_
int dict[5][4];
dict[2][3] = 7;
printf("%d\n", *(*(dict + 2)+3) ); // outputs 7
*(*(dict+i)+3) == dict[i][3];
// &i = 2000
int *next_int = &i + 1; //next_int => 2004 (int is 4 byte); (char is 1 byte)
char **dict = 3000;
dict+1 => 3004 // pointer is 4 byte
sizeof(node->word); // sizeof gives 4. word is a pointer
char static_word[10];
sizeof(static_word) => 10; //alr defined above
char *static_word[10];
sizeof(static_word) = 40 // pointer is 4 byte x 10 -> 40
=====================================================================
---------------------------------------------------------------------
Postfix Operators (binds more tightly): ++, --, []
---------------------------------------------------------------------
int array[] = {45,67,89};
int *ptr = array; // same as: int *ptr; ptr = array;
*(ptr++) is the same as *ptr++ (both returns 45)
array[0]; (return 45; but the [] in array[0] has _nothing_to_do_ with arrays)
array[1]; (return 67, same as *(array+1);)
int *p = &array[1]; // p is a pointer to array[1] (aka the obj `67').
// &array[1] is equiv (array+1);
p[1]; // gives 89. why?
// same as *(p+1) eq *(&array[1] + 1) eq *(array+1 + 1) eq *(array + 2);
int arr[3] = {12,23,34};
int *ptr = arr;
*ptr++; is equiv to *(ptr++); // res: 12
*++ptr; is equiv to *(++ptr); // res: 23
++*ptr; is equiv to ++(*ptr); // res: 23+1 = 24
++*++ptr; is equiv to ++(*(++ptr)); // res: 23+1 = 24
++*ptr++; is equiv to ++(*(ptr++)); // res: 12+1 = 13
void foo(int arr[]); is equiv to: void foo(int *arr);
int arr[]; // illegal byitself. need: int arr[10]; or: int arr[] = {1};
int *arr; //legal
char *word = "HelloWorld"; // a pointer; to a string _constant_
// if try to modify: segfault, or unpredictable behaviour
char word[] = "HelloWorld"; // an array, includes '\0'
Multiple Indirection
int a = 3;
int *b = &a;
int **c = &b;
int ***d = &c;
*d == c; Dereferencing an (int ***) once gets you an (int **) (3 - 1 = 2)
**d == *c == b; Dereferencing an (int ***) twice, or an (int **) once,
gets you an (int *) (3 - 2 = 1; 2 - 1 = 1)
***d == **c == *b == a == 3;
Dereferencing an (int ***) thrice, or an (int **) twice, or an (int *) once,
gets you an int (3 - 3 = 0; 2 - 2 = 0; 1 - 1 = 0)
===============================================================================
-------------------------------------------------------------------------------
Structures
-------------------------------------------------------------------------------
struct point{
int x; int y;
}; (note the ";" here)
In a method, we can also write:
struct {int x; int y;} somepoint;
struct rect{
struct point pt1, pt2; // note how we ``combine'' into one line
};
if p is a pointer to a structure,
then p->member-of-structure referes to the particular member
'->' is short-hand for (*p).member
Note that . and -> associate from left to right
struct rect r, *rp = &r;
these four exprs are equiv:
r.pt1.x
rp->pt1.x
(r.pt1).x // cannot wrote (r.pt1)->x since r.pt1 is not a pointer
(rp->pt1).x
Node **node;
(*node)->next is NOT equiv to: *node->next;
the second one fetches whatever `next' points to, i.e. *(node->next)
typedef struct stu{
char *id;
}Student;
We can write:
typedef struct{
char *id;
}Student;
We can also write:
struct Foo{ int dat; };
typedef struct Foo Foo;
Student *student; Student s;
sizeof(Student) == sizeof(*student) == sizeof(struct stu) == sizeof(s);
sizeof is an operator
Consider:
Student *student = malloc(5*sizeof(Student));
students[1].x is valid
students[1]->student is invalid because student[1] is not a pointer
(*(students+1)).x is valid
===============================================================================
-------------------------------------------------------------------------------
Etc
-------------------------------------------------------------------------------
Consider:
int *p;
*p = 'a';
what happens?
ans: segfault. no memory is allocated for the dereferencing operation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment