SlideShare a Scribd company logo
Saurav Mukherjee
https://www.linkedin.com/in/sauravmukherjee
June 2005
Complex C - declarations &
‘typedef’
1
Introduction
C is an immensely powerful programming language. It may appear as both a high-level and a low-
level programming language at the same time. It offers wide range of facilities /options to its
programmer. But, at times, it can get cryptic and its expressions can become mind-boggling. All of us
(i.e., C-programmers), at some time or other, got awe-inspired by the complexity of a C-declaration. In
this paper, I try to decipher some of those much-revered C-declarations and then utilize typedef
keyword of C language to simplify them. Along the way, I would enumerate few simple thumb rules,
which can enable us to read those declarations easily.
Reading Declarations in C
Let us begin with some straightforward declarations, e.g.,
int i; // ‘i’ is an integer
float *f; // ‘f’ is a pointer to a float
We can go beyond the basic types and see some user defined ones.
double *some_func (struct my_struct *st);
/* This is a function declaration. A function called some_func is being declared. It takes a pointer to a
structure of type my_struct and returns a pointer to variable of type double. */
But to really understand these, we need to understand how the compiler sees them. And before
getting into that, I would like to put down some examples, which I am going to use through out this
paper.
1. char * arr [25]; // arr is an array of 25 pointers to char OR is a pointer to an array of 25 chars?
2. long (* ptr_fn) (void);
3. int (*(* cryptic) (long)) [10];
4. float *(*(* r_u_mad) (int)) (double);
2
Thumb Rules
We have come across some thumb rules which makes life easier in understanding C-declarations.
Here they go:
1. First, read the variable that is being declared.
2. With the variable at the center, start spiraling out in anti-clockwise direction.
3. Use the following clues:
a. * means “pointer to”
b. [] means “array of”
c. () means “function taking … and returning …”
d. Read structure, union or enumeration at a single go. E.g., ‘struct st’, ‘union u’ or
‘enum en’.
e. Read adjacent collection of []’s (e.g., [][] - multi-dimensional arrays) all at once.
3
Examples Explained
With these thumb-rules, let us see what the examples have in store for us:
Example 1
char *arr [25];
1. The name of the variable being declared is “arr”.
2. Moving right from here (i.e., spiraling out in anti-clockwise direction), we get [25]; hence, we
say “array of 25”.
3. Spiraling forward anti-clockwise, we find *. Hence, “pointer(s) to”.
4. Finally, between ‘]’ and ‘;’, we get ‘char’, i.e. “character”.
Putting the pieces together, we get the following:
“arr is an array of 25 pointers to character”, OR “arr is an array containing 25 elements, each
element being a pointer to a character”.
Example 2
Moving on to the next example…
long (* ptr_fn) (void);
1. The variable is “ptr_fn”.
2. Spiraling inside the parenthesis, “pointer to”.
3. Next is … “function taking no parameters and returning”.
4. Lastly, “long”.
Hence, “ptr_fn is a pointer to a function taking no parameters and returning a long”.
Example 3
Let’s go to the next example…
4
int (*(* cryptic) (long)) [10];
1. “cryptic” is the variable being declared here.
2. It is a “pointer to”
3. “function taking a long and returning”
4. “pointer to”
5. “an array of 10”
6. “int”.
Hence, “cryptic is a pointer to a function taking a long and returning a pointer to an array of 10
integers”.
Example 4
The last example….
float *(*(* r_u_mad) (int)) (double);
1. “r_u_mad”
2. “pointer to”
3. “function taking an int and returning”
4. “pointer to”
5. “function taking a double and returning”
6. “pointer to”
7. “float”
Hence, “r_u_mad is a pointer to a function taking an integer and returning a pointer to a function
taking a double and returning a pointer to a float”.
Finally, we are thorough!! But things do not have to be this difficult! C is powerful enough to make
these declarations simple. We just need to remember the thumb-rules, which we formed to
circumvent the eccentricity of some whiz kid and apply a few more to use typedef for the same
purpose. Although these examples still inspire the same awe and reverence as it was doing when we
were at on page 1 in ‘Introduction’ section, let us move forward and simply them.
5
On the way to Simplification
typedef is C’s boon to us when we are caught in these kinds of circumstances. To avoid writing those
complex and circuitous declarations, we can leverage this keyword. I am going to use the same
examples as above to show how we can use typedef effectively. Steps to simplification are easy.
Apply the ‘divide & conquer’ rule to break the declaration into smaller steps and give them to the
compiler for creating easy-to-grasp types.
An interesting way to understand typedef may be to ignore it! Read it as if a variable is being
declared - just remember that once the variable is completely read, the complier declares a type
rather than a variable. It becomes a completely new compiler type and as valid as any basic data
type.
6
Examples Revisited
Let us go to the examples:
Simplify Example 1
char *arr [25];
“arr is an array of 25 pointers to character”
Starting from the end, let us create a new type, “pointer to character”. If we write,
char * pt_ch;
we declare a variable ‘pt_ch’ of type “pointer to character”. Putting a typedef before it, we get the
new type “pointer to character”.
typedef char * pt_ch;
Before proceeding, let us take a quick look at another benefit that we can derive from this - relieving
us from the dilemma of where to put ‘*’ while declaring a pointer.
Both the following declarations will declare a pointer to a character.
char* ch1;
char *ch2;
But if we need to declare them together, will the following be enough?
char* ch1, ch2;
Answer is a ‘no’. ‘ch1’ is a pointer to a character, but ‘ch2’ is just a character. But if we use the new
type, which we have just created, the confusion will not arise.
pt_ch ch1, ch2;
The above statement declares both ‘ch1’ and ‘ch2’ as pointers to character.
Coming back to the original problem, creating an “array of 25 pointers to character” is now just like
declaring a variable of any basic type.
pt_ch arr[25];
Let us move on to the next example.
7
Simplify Example 2
long (* ptr_fn) (void);
“ptr_fn is a pointer to a function taking no parameters and returning a long”.
Attacking the last portion first, we create a new type, “function taking no parameters and returning a
long” as follows:
typedef long fn_type (void);
The function prototype is preceded by a typedef to create the new type. Now we can declare ptr_fn
as easily as below.
fn_type *ptr_fn;
/* One more level of typedef is also possible, but do we really need that? */
Let us have a look at the 3rd example.
Simplify Example 3
int (*(* cryptic) (long)) [10];
“cryptic is a pointer to a function taking a long and returning a pointer to an array
of 10 integers”.
As usual we begin with the last part, which is “pointer to an array of 10 integers”. Dividing it in even
smaller steps, we generate the types as following:
typedef int arr_of_10_int[10];
typedef arr_of_10_int *p_arr_10_int;
Now, for a function taking a long as parameter and returning p_arr_10_int, we have,
typedef p_arr_10_int fn_t(long);
Now, just create ‘cryptic’ as following:
fn_t *cryptic;
8
The last example
Simplify Example 4
float *(*(* r_u_mad) (int)) (double);
“r_u_mad is a pointer to a function taking an integer and returning a pointer to a
function taking a double and returning a pointer to a float”.
Let us approach this awesome example also in the same way as we did before.
We start with the last part, i.e., “pointer to float”.
typedef float *ptf;
Now we find “function taking a double and returning ptf”. Hence, we write,
typedef ptf fn_dble(double);
Moving forward, we get “pointer to fn_dble”. Therefore,
typedef fn_dble *p_fn_dble;
Finally, “function taking an integer and returning p_fn_dble” -
typedef p_fn_dble maddening(int);
Hence, the declaration now becomes
maddening r_u_mad;
This brings us to an end of my venture of putting down some tips on how to simplify complex
declarations in C.

More Related Content

PPT
01.dasar fuel injection
PDF
三相誘導モーターのベアリング交換
PPT
Complicated declarations in c
PPT
C Programming Intro.ppt
PPTX
C data types, arrays and structs
PDF
Pc module1
PDF
Embedded C The IoT Academy
PPT
Advanced C programming
01.dasar fuel injection
三相誘導モーターのベアリング交換
Complicated declarations in c
C Programming Intro.ppt
C data types, arrays and structs
Pc module1
Embedded C The IoT Academy
Advanced C programming

Similar to Complex C-declarations & typedef (20)

PDF
C programming session8
PDF
C programming session8
PPTX
C Programming Unit-4
PPTX
data types in C programming
PDF
cassignmentii-170424105623.pdf
PPTX
Advance topics of C language
PDF
introduction to programming using ANSI C
PPTX
Computer science ( Structures In C ) Ppt
PPT
Data Handling
PPTX
Unit 3(Arrays).pptx arrays topics in the c lang
DOCX
fds unit1.docx
PPTX
Concept of c data types
PPTX
C language
PPT
A File is a collection of data stored in the secondary memory. So far data wa...
PPT
introduction2_programming slides briefly exolained
PPT
Chapter02.PPT
PPT
Introduction to Problem Solving C Programming
PPT
c programming 2nd chapter pdf.PPT
PDF
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
C programming session8
C programming session8
C Programming Unit-4
data types in C programming
cassignmentii-170424105623.pdf
Advance topics of C language
introduction to programming using ANSI C
Computer science ( Structures In C ) Ppt
Data Handling
Unit 3(Arrays).pptx arrays topics in the c lang
fds unit1.docx
Concept of c data types
C language
A File is a collection of data stored in the secondary memory. So far data wa...
introduction2_programming slides briefly exolained
Chapter02.PPT
Introduction to Problem Solving C Programming
c programming 2nd chapter pdf.PPT
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
Ad

More from Saurav Mukherjee (6)

PDF
Linear regression theory
PDF
Presentation Skills
PPTX
Enterprise Agile Adoption
PDF
Enterprise Data Management - Data Lake - A Perspective
PDF
Tire Pressure Monitoring System (TPMS) - An Introduction
PDF
Competitive positioning and routes to market for a high-technology innovation...
Linear regression theory
Presentation Skills
Enterprise Agile Adoption
Enterprise Data Management - Data Lake - A Perspective
Tire Pressure Monitoring System (TPMS) - An Introduction
Competitive positioning and routes to market for a high-technology innovation...
Ad

Recently uploaded (20)

PPTX
Introduction to Artificial Intelligence
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
history of c programming in notes for students .pptx
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Nekopoi APK 2025 free lastest update
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Online Work Permit System for Fast Permit Processing
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Digital Strategies for Manufacturing Companies
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Design an Analysis of Algorithms II-SECS-1021-03
Introduction to Artificial Intelligence
Design an Analysis of Algorithms I-SECS-1021-03
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Understanding Forklifts - TECH EHS Solution
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
How to Choose the Right IT Partner for Your Business in Malaysia
history of c programming in notes for students .pptx
Which alternative to Crystal Reports is best for small or large businesses.pdf
PTS Company Brochure 2025 (1).pdf.......
Nekopoi APK 2025 free lastest update
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
2025 Textile ERP Trends: SAP, Odoo & Oracle
Odoo Companies in India – Driving Business Transformation.pdf
Online Work Permit System for Fast Permit Processing
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Digital Strategies for Manufacturing Companies
Wondershare Filmora 15 Crack With Activation Key [2025
How to Migrate SBCGlobal Email to Yahoo Easily
Design an Analysis of Algorithms II-SECS-1021-03

Complex C-declarations & typedef

  • 2. 1 Introduction C is an immensely powerful programming language. It may appear as both a high-level and a low- level programming language at the same time. It offers wide range of facilities /options to its programmer. But, at times, it can get cryptic and its expressions can become mind-boggling. All of us (i.e., C-programmers), at some time or other, got awe-inspired by the complexity of a C-declaration. In this paper, I try to decipher some of those much-revered C-declarations and then utilize typedef keyword of C language to simplify them. Along the way, I would enumerate few simple thumb rules, which can enable us to read those declarations easily. Reading Declarations in C Let us begin with some straightforward declarations, e.g., int i; // ‘i’ is an integer float *f; // ‘f’ is a pointer to a float We can go beyond the basic types and see some user defined ones. double *some_func (struct my_struct *st); /* This is a function declaration. A function called some_func is being declared. It takes a pointer to a structure of type my_struct and returns a pointer to variable of type double. */ But to really understand these, we need to understand how the compiler sees them. And before getting into that, I would like to put down some examples, which I am going to use through out this paper. 1. char * arr [25]; // arr is an array of 25 pointers to char OR is a pointer to an array of 25 chars? 2. long (* ptr_fn) (void); 3. int (*(* cryptic) (long)) [10]; 4. float *(*(* r_u_mad) (int)) (double);
  • 3. 2 Thumb Rules We have come across some thumb rules which makes life easier in understanding C-declarations. Here they go: 1. First, read the variable that is being declared. 2. With the variable at the center, start spiraling out in anti-clockwise direction. 3. Use the following clues: a. * means “pointer to” b. [] means “array of” c. () means “function taking … and returning …” d. Read structure, union or enumeration at a single go. E.g., ‘struct st’, ‘union u’ or ‘enum en’. e. Read adjacent collection of []’s (e.g., [][] - multi-dimensional arrays) all at once.
  • 4. 3 Examples Explained With these thumb-rules, let us see what the examples have in store for us: Example 1 char *arr [25]; 1. The name of the variable being declared is “arr”. 2. Moving right from here (i.e., spiraling out in anti-clockwise direction), we get [25]; hence, we say “array of 25”. 3. Spiraling forward anti-clockwise, we find *. Hence, “pointer(s) to”. 4. Finally, between ‘]’ and ‘;’, we get ‘char’, i.e. “character”. Putting the pieces together, we get the following: “arr is an array of 25 pointers to character”, OR “arr is an array containing 25 elements, each element being a pointer to a character”. Example 2 Moving on to the next example… long (* ptr_fn) (void); 1. The variable is “ptr_fn”. 2. Spiraling inside the parenthesis, “pointer to”. 3. Next is … “function taking no parameters and returning”. 4. Lastly, “long”. Hence, “ptr_fn is a pointer to a function taking no parameters and returning a long”. Example 3 Let’s go to the next example…
  • 5. 4 int (*(* cryptic) (long)) [10]; 1. “cryptic” is the variable being declared here. 2. It is a “pointer to” 3. “function taking a long and returning” 4. “pointer to” 5. “an array of 10” 6. “int”. Hence, “cryptic is a pointer to a function taking a long and returning a pointer to an array of 10 integers”. Example 4 The last example…. float *(*(* r_u_mad) (int)) (double); 1. “r_u_mad” 2. “pointer to” 3. “function taking an int and returning” 4. “pointer to” 5. “function taking a double and returning” 6. “pointer to” 7. “float” Hence, “r_u_mad is a pointer to a function taking an integer and returning a pointer to a function taking a double and returning a pointer to a float”. Finally, we are thorough!! But things do not have to be this difficult! C is powerful enough to make these declarations simple. We just need to remember the thumb-rules, which we formed to circumvent the eccentricity of some whiz kid and apply a few more to use typedef for the same purpose. Although these examples still inspire the same awe and reverence as it was doing when we were at on page 1 in ‘Introduction’ section, let us move forward and simply them.
  • 6. 5 On the way to Simplification typedef is C’s boon to us when we are caught in these kinds of circumstances. To avoid writing those complex and circuitous declarations, we can leverage this keyword. I am going to use the same examples as above to show how we can use typedef effectively. Steps to simplification are easy. Apply the ‘divide & conquer’ rule to break the declaration into smaller steps and give them to the compiler for creating easy-to-grasp types. An interesting way to understand typedef may be to ignore it! Read it as if a variable is being declared - just remember that once the variable is completely read, the complier declares a type rather than a variable. It becomes a completely new compiler type and as valid as any basic data type.
  • 7. 6 Examples Revisited Let us go to the examples: Simplify Example 1 char *arr [25]; “arr is an array of 25 pointers to character” Starting from the end, let us create a new type, “pointer to character”. If we write, char * pt_ch; we declare a variable ‘pt_ch’ of type “pointer to character”. Putting a typedef before it, we get the new type “pointer to character”. typedef char * pt_ch; Before proceeding, let us take a quick look at another benefit that we can derive from this - relieving us from the dilemma of where to put ‘*’ while declaring a pointer. Both the following declarations will declare a pointer to a character. char* ch1; char *ch2; But if we need to declare them together, will the following be enough? char* ch1, ch2; Answer is a ‘no’. ‘ch1’ is a pointer to a character, but ‘ch2’ is just a character. But if we use the new type, which we have just created, the confusion will not arise. pt_ch ch1, ch2; The above statement declares both ‘ch1’ and ‘ch2’ as pointers to character. Coming back to the original problem, creating an “array of 25 pointers to character” is now just like declaring a variable of any basic type. pt_ch arr[25]; Let us move on to the next example.
  • 8. 7 Simplify Example 2 long (* ptr_fn) (void); “ptr_fn is a pointer to a function taking no parameters and returning a long”. Attacking the last portion first, we create a new type, “function taking no parameters and returning a long” as follows: typedef long fn_type (void); The function prototype is preceded by a typedef to create the new type. Now we can declare ptr_fn as easily as below. fn_type *ptr_fn; /* One more level of typedef is also possible, but do we really need that? */ Let us have a look at the 3rd example. Simplify Example 3 int (*(* cryptic) (long)) [10]; “cryptic is a pointer to a function taking a long and returning a pointer to an array of 10 integers”. As usual we begin with the last part, which is “pointer to an array of 10 integers”. Dividing it in even smaller steps, we generate the types as following: typedef int arr_of_10_int[10]; typedef arr_of_10_int *p_arr_10_int; Now, for a function taking a long as parameter and returning p_arr_10_int, we have, typedef p_arr_10_int fn_t(long); Now, just create ‘cryptic’ as following: fn_t *cryptic;
  • 9. 8 The last example Simplify Example 4 float *(*(* r_u_mad) (int)) (double); “r_u_mad is a pointer to a function taking an integer and returning a pointer to a function taking a double and returning a pointer to a float”. Let us approach this awesome example also in the same way as we did before. We start with the last part, i.e., “pointer to float”. typedef float *ptf; Now we find “function taking a double and returning ptf”. Hence, we write, typedef ptf fn_dble(double); Moving forward, we get “pointer to fn_dble”. Therefore, typedef fn_dble *p_fn_dble; Finally, “function taking an integer and returning p_fn_dble” - typedef p_fn_dble maddening(int); Hence, the declaration now becomes maddening r_u_mad; This brings us to an end of my venture of putting down some tips on how to simplify complex declarations in C.