0% found this document useful (0 votes)
7 views26 pages

04 Advanced C Programming

The document discusses advanced C programming concepts, focusing on the scope of symbol names, which includes program, file, function, and block scopes. It explains the importance of defining symbols in the narrowest scope possible and highlights issues related to operator precedence and associativity. Additionally, it provides examples of common pitfalls in understanding scope and precedence in C programming.

Uploaded by

b'stard/tempest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views26 pages

04 Advanced C Programming

The document discusses advanced C programming concepts, focusing on the scope of symbol names, which includes program, file, function, and block scopes. It explains the importance of defining symbols in the narrowest scope possible and highlights issues related to operator precedence and associativity. Additionally, it provides examples of common pitfalls in understanding scope and precedence in C programming.

Uploaded by

b'stard/tempest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 26

Advanced C Programming

from Expert C Programming: Deep C Secrets by


Peter van der Linden

CIS*2450
Advanced Programming Concepts

1
Topics
• Scope of symbol names
– 4 flavours

• Precedence of operators
– associativity
– syntax of declarations with multiple operators

2
Scope
• Definition
– Region over which you can access a variable by
name.
• There are 4 types of scope:
– Program scope … widest
– File scope
– Function scope
– Block scope … narrowest

3
Scoping Principle
• Always define a symbol in the narrowest
scope that works

• Reasons?

4
Program Scope
• The variable is active among all source files
that make up the executable.
– In C, all functions
– Global (extern) variables

• How does it work?

5
External Symbols
• Program scope symbols passed to linker
in .o file
– External definition, “extdef”
– External reference, “extref”
• In linked executable, each external symbol:
– Exactly 1 extdef, or else…
• “undefined external” “multiply defined external”
– Any number of extrefs
• substituted with final memory address of symbol
6
“Externals”
• Having “program scope” (external symbols)
is a common requirement
– assembly language
– all kinds of programming languages
– allows big program to be linked together out of
small modules
• Each language has own convention for
designating extdef & extref
7
Using Program Scope in C
• Function
– extdef: MARCFILE *useMarcFile(FILE *filep){…}
• definition only appears in one .c (marcutil.c)
– extref: MARCFILE *useMarcFile(FILE *filep);
• prototype declaration (.h) included in many .c files
• Variable (don’t have any in A1)
– extdef: MARCFILE *libfile;
• definition only appears in one .c, outside any function
• can initialize: type varname = initial_value;
– extref: extern MARCFILE *libfile;
• declaration appears anywhere, in/outside functions
8
File Scope
• A variable is active from its declaration
point to the end of the file.
– In C, static variables.

• If variable defined outside any function…


– would normally be “program scope” (global)
– “static” keyword keeps definition from being
passed to linker → doesn’t become external

9
Scope vs. Storage Class
• “Static” storage
– One copy of variable in executable program
– Applies to both program scope (global variables) & file
scope (“static” variables)

• Issue confused in C/C++ (real “deep secret” )


– Program scope (globals) are static in nature, but
without “static” keyword
– If you add “static” keyword, not global anymore!
10
Contrast Automatic Storage
• Associated with functions
– Arguments
– Local variables inside function
• Fresh temporary copy created on stack every time
function called
– Copy can be initialized (same value each time)
– Copy goes away when function returns to caller
– Allows recursion to work!
• “static” keyword changes local variable from
automatic to static storage class
– Initialization effective once, when program started
11
Function Scope
• Active from the beginning to the end of a
function.
– In C, only goto labels have function scope;
therefore you will never see them 

12
Block Scope
• The variable is active from its declaration
point to the end of the block in which it was
declared.
– In C, these are local variables.
– Includes function’s parameters

13
Example
int i; /* Program scope */
static int j; /* File scope */
func ( int k ) { /* func is program scope,
k is block scope */
int m; /* Block scope */
….
}
/* which are static storage, auto? */

14
What Happens?
func() {
int a = 11;
{
int b = 10;
}
printf ( “%d %d\n”,a,b);
}
Won’t work!
The variable b is inside a block and therefore is not visible
to the rest of the function.

15
What Happens?
newfunc() {
int a = 11;
{
int b = 10;
printf ( “%d\n”,b);
}
printf ( “%d\n”,a);
}

WORKS!
16
Precedence of Operators
• Definition
– Determines the order in which operators are
evaluated.
– Operators are used to calculate values for both
numeric and pointer expressions
• Operators also have an associativity which
is used to determine the order in which
operands are grouped with operators.
17
Associativity
• Applies with 2 or more operators of same
precedence:
A op1 B op2 C op3 D
– Answers question: Which op is done first?
• Associativity can be either Left-to-Right or
Right-to-Left

18
Associativity
• Left-to-Right is most common
a + b – c;
– The + and – operators are both evaluated left-
to-right so the expression is
“a plus b, then subtract c”
– Equivalent to: (a + b) – c;

19
Associativity
• Right-to-Left is rare
a = b = c;
– This expression is read
“assign c to b, then to a”
– Equivalent to: a = (b = c);
– Meaningful because in C assignment operator
is an expression with a value

20
Problems with Precedence
• The precedence of some operators produces
problems when they create behaviours
which are unexpected.

21
Problems with Precedence
• Pointer to structure: *p.f
– Expectation: the field of what p points to
• (*p).f
– Actually: p.f gives a compile error
• *(p.f)
– Why: . is higher than *
– Note: The -> operator was made to correct this.
• p->f

22
Problems with Precedence
• int *ap[]
– Expectation: ap is a ptr to an array of ints
• int (*ap)[]
– Actually: ap is an array of pointers-to-int
• int *(ap[])
– Why: [] is higher than *
– Note: usually found in declarations.

23
Problems with Precedence
• int *fp()
– Expectation: fp is a ptr to a function returning
an int
• int (*fp)()
– Actually: fp is a function returning a ptr-to-int
• int *(fp())
– Why: () is higher than *
– Note: usually found in declarations.
24
Problems with Precedence
• c = getchar() != EOF
– Expectation: ( c = getchar() ) != EOF
– Actually: c = (getchar() != EOF)
• c is set equal to the true/false value
– Why: == and != have higher precedence than
assignment

25
Solution to Precedence Problems
• When in doubt…

Use parentheses!!!

• Better still, use parentheses anyway


– You may not be in doubt, but the next reader
may be

26

You might also like