const Type*
)*
(de-reference operator)&
(address-of operator)Type* ptr;
Pointers should always be initialized
(use NULL
if needed)
Type* ptr = NULL;
int a = 5;
int* a_ptr = &a;
*a_ptr += 5;
Complete Program
#include <stdio.h>
int main() {
int a = 5;
int* a_ptr = &a; // &: address-of operator
*a_ptr += 5; // *: dereference operator
printf("updated value: %d (at %p - %zu bytes)\n", a, a_ptr, sizeof(a_ptr));
return 0;
}
#include <stdio.h>
int main() {
int a = 4, b = 5;
int* a_ptr = &a; // when starting, it is easiest to have a pre- or suffix
int* b_ptr = &b; // for every pointer in your programs
int** p = &a_ptr;
*p = NULL; // set a_ptr to invalid location
*p = b_ptr;
**p *= **p; // use multiple lines to make readable
printf("a = %d, b = %d\n", a, b);
return 0;
}
Avoid changing parameters whenever possible!
#include <stdio.h>
void update(int* a_ptr,int *b_ptr) {
*a_ptr += 10; // assign new value to memory address of `a`
*b_ptr = 100; // assign new value to `b`
// still possible to return a value if needed
}
int main() {
int a=4;
int b=5;
int* a_ptr = &a; // &: address-of operator
update(a_ptr, &b);
printf("updated values: %d %d\n", a, b);
return 0;
}
#include <stdio.h>
int sum(const int* array, int count) {
int value = 0;
while (count--) {
value += *array++;
}
return value;
}
int main() {
int array[] = {1, 2, 3, 4, 5, 6};
int value = sum(array, sizeof(array) / sizeof(int));
printf("sum: %d\n", value);
return 0;
}
#include <stdio.h>
#include <ctype.h>
void upper(char* text) {
while (*text) { // string ends with the `\0` character
*text = toupper(*text); // return upper case character
text++;
}
}
int main() {
char name[] = "Chris";
upper(name);
printf("%s\n", name);
return 0;
}
The arrow operator ->
allows direct access to members
when using pointers.
#include <stdio.h>
typedef struct {int year; int month; int day;} IsoDate;
void print_date(const IsoDate* d) {
printf("%04d-%02d-%02d\n", (*d).year, d->month, d->day);
}
int main() {
IsoDate date = {2022, 1, 11};
print_date(&date);
return 0;
}