Last active
April 7, 2017 07:41
-
-
Save thatseeyou/4187f79b0df1717f1ff3368c6238820a to your computer and use it in GitHub Desktop.
Various C pointer examples
This file contains hidden or 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
/* | |
* C pointer examples | |
* | |
* 2017-07-17 ([email protected]) | |
* - initial write | |
* | |
* Reference: http://unixwiz.net/techtips/reading-cdecl.html | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
int main(int argc, char *argv[], char *envp[]) | |
{ | |
// Pointer to int | |
{ | |
{ | |
int a = 1, b = 2; | |
int *pA = &a, *pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
{ | |
int (a) = 1, (b) = 2; | |
int (*pA) = &a, (*pB) = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
*pA = 10; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
pA = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
} | |
// Pointer to const int | |
{ | |
{ | |
const int a = 1, b = 2; | |
const int *pA = &a, *pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
// a = 10; | |
// ERROR | |
// *pA = 10; | |
pA = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
{ | |
const int (a) = 1, (b) = 2; | |
const int (*pA) = &a, (*pB) = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
//a = 10; | |
// ERROR | |
//*pA = 10; | |
pA = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
{ | |
// int const === const int | |
int const a = 1, b = 2; | |
int const *pA = &a, *pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
// a = 10; | |
// ERROR | |
// *pA = 10; | |
pA = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
} | |
// Pointer to const int ( -> non-const int) | |
{ | |
{ | |
int a = 1, b = 2; | |
const int *pA = &a, *pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
a = 10; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
//*pA = 10; | |
pA = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
} | |
} | |
// const pointer to int | |
{ | |
{ | |
int a = 1, b = 2; | |
int * const pA = &a, * const pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
a = 10; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
*pA = 10; | |
*pB = 20; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
//pA = &b; | |
//pB = &a; | |
} | |
{ | |
int a = 1, b = 2; | |
int (* const pA) = &a, (* const pB) = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
a = 10; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
*pA = 10; | |
*pB = 20; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
//pA = &b; | |
//pB = &a; | |
} | |
} | |
// const pointer to const int | |
{ | |
{ | |
const int a = 1, b = 2; | |
const int * const pA = &a, * const pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
// a = 10; | |
// ERROR | |
//*pA = 10; | |
// ERROR | |
// pA = &b; | |
} | |
{ | |
const int a = 1, b = 2; | |
const int (* const pA) = &a, (* const pB) = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
// a = 10; | |
// ERROR | |
//*pA = 10; | |
// ERROR | |
// pA = &b; | |
// pB = &a; | |
} | |
{ | |
// int const === const int | |
int const a = 1, b = 2; | |
int const * const pA = &a, * const pB = &b; | |
printf("%3d: %d, %d\n", __LINE__, *pA, *pB); | |
// ERROR | |
// a = 10; | |
// ERROR | |
// *pA = 10; | |
// ERROR | |
// pA = &b; | |
} | |
} | |
// array of pointer to int | |
{ | |
{ | |
int a = 1, b = 2; | |
int *pA[] = {&a, &b}, *pB[] = {&b, &a}; | |
} | |
{ | |
int a = 1, b = 2; | |
int *(pA[]) = {&a, &b}, *(pB[]) = {&b, &a}; | |
} | |
{ | |
int a = 1, b = 2; | |
int (*(pA[])) = {&a, &b}, (*(pB[])) = {&b, &a}; | |
} | |
} | |
// pointer to array of int | |
{ | |
{ | |
int a[3] = {1, 2, 3}, b[2] = {4, 5}; | |
int (*pA)[3] = &a, (*pB)[2] = &b; | |
printf("%3d: %d, %d, %d\n", __LINE__, a[0], a[1], a[2]); | |
a[0] = 10; | |
(*pA)[1] = 20; | |
*pA[2] = 30; // UNEXPECTED BEHAVIOR, equivalent to *(pA[2]) = 30; | |
printf("%3d: %d, %d, %d\n", __LINE__, a[0], a[1], a[2]); | |
} | |
{ | |
// the number of array is inferenced | |
int a[3] = {1, 2, 3}, b[] = {4, 5}; | |
int (*pA)[] = &a, (*pB)[2] = &b; | |
// ERROR | |
// int (*pC)[4] = &a; | |
} | |
// cf: pointer to first element of array | |
{ | |
int a[] = {1, 2, 3}, b[2] = {4, 5}; | |
int *pA = a, (*pB) = b; | |
int *pA2 = &a[0], (*pB2) = &b[0]; | |
} | |
} | |
// pointer to array of const int | |
{ | |
{ | |
const int a[] = {1, 2, 3}, b[] = {4, 5, 6}; | |
const int (*pA)[] = &a, (*pB)[] = &b; | |
printf("%3d: %d, %d, %d\n", __LINE__, a[0], a[1], a[2]); | |
// ERROR | |
// a[0] = 10; | |
// (*pA)[1] = 20; | |
pA = &b; | |
printf("%3d: %d, %d, %d\n", __LINE__, (*pA)[0], (*pA)[1], (*pA)[2]); | |
} | |
} | |
// const pointer to array of const int | |
{ | |
{ | |
const int a[] = {1, 2, 3}, b[] = {4, 5, 6}; | |
const int (* const pA)[] = &a, (* const pB)[] = &b; | |
printf("%3d: %d, %d, %d\n", __LINE__, a[0], a[1], a[2]); | |
// ERROR | |
// a[0] = 10; | |
// (*pA)[1] = 20; | |
// ERROR | |
// pA = &b; | |
} | |
} | |
{ | |
{ | |
char a[] = "abc"; | |
char (*pA)[] = &a; | |
printf("%3d: %s(%c-%c-%c)\n", __LINE__, a, a[0], a[1], a[2]); | |
a[0] = 'A'; | |
printf("%3d: %s(%c-%c-%c)\n", __LINE__, a, a[0], a[1], a[2]); | |
// ERROR: overflow | |
// a[4] = 'D'; | |
(*pA)[1] = 'B'; | |
printf("%3d: %s(%c-%c-%c)\n", __LINE__, (*pA), (*pA)[0], (*pA)[1], (*pA)[2]); | |
// ERROR: overflow | |
//(*pA)[4] = 'X'; | |
} | |
{ | |
char a[4] = "abc"; | |
char (*pA)[4] = &a; | |
} | |
{ | |
char *a = "abc"; | |
char *pA = a; | |
printf("%3d: %s(%c-%c-%c)\n", __LINE__, a, a[0], a[1], a[2]); | |
// ERROR: Bus error | |
// a[0] = 'A'; | |
} | |
{ | |
const char a[] = "abc"; | |
const char (*pA)[] = &a; | |
} | |
} | |
// pointer to array of array(= two dimensional array) of int | |
{ | |
{ | |
int a[][2] = { {1,2}, {3,4} }, b[][2] = { {5,6}, {7,8} }; | |
int (*pA)[][2] = &a, (*pB)[][2] = &b; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, a[0][0], a[0][1], a[1][0], a[1][1]); | |
// ( ) is necessary | |
(*pA)[0][0] = 10; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, a[0][0], a[0][1], a[1][0], a[1][1]); | |
pA = &b; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, (*pA)[0][0], (*pA)[0][1], (*pA)[1][0], (*pA)[1][1]); | |
} | |
{ | |
int a[][2] = { {1,2}, {3,4} }, b[][2] = { {5,6}, {7,8} }; | |
int (*pA)[2] = a, (*pB)[2] = b; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, a[0][0], a[0][1], a[1][0], a[1][1]); | |
pA[0][0] = 10; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, a[0][0], a[0][1], a[1][0], a[1][1]); | |
pA = b; | |
printf("%3d: (%d,%d), (%d,%d)\n", __LINE__, pA[0][0], pA[0][1], pA[1][0], pA[1][1]); | |
} | |
} | |
// array of pointer to array of int | |
{ | |
{ | |
int a1[] = {1,2}, a2[] = {3,4}, a3[] = {5,6}; | |
int (*(pA[]))[2] = { &a1, &a2, &a3 }; | |
// a1 == &a1 | |
printf("%3d: a1 = %p, &a1 = %p\n", __LINE__, a1, &a1); | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, a1[0], a1[1], a2[0], a2[1], a3[0], a3[1]); | |
a1[0] = 10; | |
(*(pA[0]))[1] = 20; | |
(*pA[1])[0] = 30; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, (*pA[0])[0], (*pA[0])[1], (*pA[1])[0], (*pA[1])[1], (*pA[2])[0], (*pA[2])[1]); | |
// ERROR | |
//(*pA[0])[2] = 100; | |
// | |
// NO ERROR but Segmentation fault | |
//(*pA[3])[0] = 1000; | |
} | |
// array of pointer to first element of array of int | |
{ | |
int a1[] = {1,2}, a2[] = {3,4}, a3[] = {5,6}; | |
int *(pA[]) = { a1, a2, a3 }; | |
// a1 == &a1 | |
printf("%3d: a1 = %p, &a1 = %p\n", __LINE__, a1, &a1); | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, a1[0], a1[1], a2[0], a2[1], a3[0], a3[1]); | |
a1[0] = 10; | |
(pA[0])[1] = 20; | |
pA[1][0] = 30; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, pA[0][0], pA[0][1], pA[1][0], pA[1][1], pA[2][0], pA[2][1]); | |
// NO CHECK FOR INDEX OVERFLOW | |
pA[0][2] = 100; | |
// NO ERROR but segmentation fault | |
// pA[3][0] = 1000; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, pA[0][0], pA[0][1], pA[1][0], pA[1][1], pA[2][0], pA[2][1]); | |
} | |
} | |
// array of pointer to array of int which is malloced | |
{ | |
{ | |
const int numCol = 2; | |
const int numRow = 3; | |
int (*a1)[numCol] = (int (*)[numCol])malloc(numCol * sizeof(int)); | |
int (*a2)[numCol] = (int (*)[numCol])malloc(numCol * sizeof(int)); | |
int (*a3)[numCol] = (int (*)[numCol])malloc(numCol * sizeof(int)); | |
int (*((*pA)[]))[numCol] = (int (*((*)[]))[numCol])malloc(numRow * sizeof(int *)); | |
(*a1)[0] = 1; (*a1)[1] = 2; (*a2)[0] = 3; (*a2)[1] = 4; (*a3)[0] = 5; (*a3)[1] = 6; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, (*a1)[0], (*a1)[1], (*a2)[0], (*a2)[1], (*a3)[0], (*a3)[1]); | |
(*pA)[0] = a1; (*pA)[1] = a2; (*pA)[2] = a3; | |
(*((*pA)[0]))[0] = 10; | |
(*((*pA)[0]))[1] = 20; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, (*a1)[0], (*a1)[1], (*a2)[0], (*a2)[1], (*a3)[0], (*a3)[1]); | |
// ERROR CHECKED | |
// (*a1)[2] = 3; | |
} | |
{ | |
const int numCol = 2; | |
const int numRow = 3; | |
int *a1 = (int *)malloc(numCol * sizeof(int)); | |
int *a2 = (int *)malloc(numCol * sizeof(int)); | |
int *a3 = (int *)malloc(numCol * sizeof(int)); | |
int *(*pA) = (int **)malloc(numRow * sizeof(int *)); | |
a1[0] = 1; a1[1] = 2; a2[0] = 3; a2[1] = 4; a3[0] = 5; a3[1] = 6; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, a1[0], a1[1], a2[0], a2[1], a3[0], a3[1]); | |
pA[0] = a1; pA[1] = a2; pA[2] = a3; | |
pA[0][0] = 10; | |
pA[0][1] = 20; | |
printf("%3d: (%d,%d), (%d,%d), (%d,%d)\n", __LINE__, a1[0], a1[1], a2[0], a2[1], a3[0], a3[1]); | |
// NOT CHECKED | |
// a1[2] = 3; | |
} | |
} | |
} |
This file contains hidden or 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
#include <stdio.h> | |
#include <stdlib.h> | |
int main(int argc, char *argv[], char *envp[]) | |
{ | |
// array of pointers to function returning int | |
{ | |
int plus(int arg1, int arg2) { | |
return arg1 + arg2; | |
} | |
int minus(int arg1, int arg2) { | |
return arg1 - arg2; | |
} | |
int x2(int arg1) { | |
return arg1 * 2; | |
} | |
// function input type is ignored | |
{ | |
int (*fp[])() = {plus, minus, x2}; | |
int result[] = {fp[0](1, 2), fp[1](2, 1), fp[2](3)}; | |
printf("%3d: %d, %d, %d\n", __LINE__, result[0], result[1], result[2]); | |
// MISSING ARGUMENT -> CHECKED | |
// result[0] = plus(1); | |
// MISSING ARGUMENT -> NOT CHECKED | |
result[0] = fp[0](1); | |
} | |
// function of (int, int) | |
{ | |
int (*fp[])(int, int) = {plus, minus}; | |
int result[] = {fp[0](1, 2), fp[1](2, 1)}; | |
printf("%3d: %d, %d\n", __LINE__, result[0], result[1]); | |
// MISSING ARGUMENT -> CHECKED | |
// result[0] = plus(1); | |
// MISSING ARGUMENT -> CHECKED | |
// result[0] = fp[0](1); | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment