09a. Variable Scope
09a. Variable Scope
1. Variable scope
2. Concept of Address
3. Storage class
2
1. Variable Scope ( 範圍 , 領域 )
• The scope of a variable determines where the variable is
accessible or useable in a program.
3
1.1. Local Scope (or Block Scope)
1 void foo(int p)
2 { p and q are only accessible inside foo().
3 int q;
4 ...
5 }
6
7 int main(void)
x is only accessible inside main().
8 {
9 int x;
10 ...
11 if (...)
12 {
13 int y;
14 ...
15 }
16 return 0;
17 }
4
1.1. Local Scope (or Block Scope)
1 void foo(int p)
2 {
3 int q;
4 ...
5 }
6
7 int main(void)
8 {
9 int x;
10 ...
11 if (...)
12 {
y is only accessible within the if-block
13 int y;
14 ...
15 }
16 return 0;
17 }
5
1.1. Local Scope (or Block Scope)
1 void foo(int p)
2 {
3 int q;
4 printf("%d", x); // Error! Accessing an identifier
5 }
6
outside its scope will result in
7 int main(void) a compile-time error.
8 {
9 int x;
10 if (...)
11 {
12 int y;
13 printf("%d", x); // OK!
14 }
15 printf("%d", y); // Error!
16 return 0;
17 }
6
1.1.1. How to make good use of local scope
1 int A, B;
2
3 ...
4
5 // When we need a variable temporarily (e.g., to
6 // swap the value between two A and B), we can
7 introduce
8 // a block and declare the "temp" variable inside.
9 {
10 int tmp; // This way, we make sure "tmp" only
11 exists
12 tmp = A; // in this block and won't introduce
13 A = B; // a conflicting name by accident.
14 B = tmp;
15 }
7
1.2. Global Scope (File Scope)
1 int universe;
2 Variables that are not declared
3 void foo() { inside of any function are
4 printf("%d\n", universe);commonly known as global
5 universe++; variable. They are accessible
6 } anywhere in the same file.
7
8 int main(void) { In this example, universe is a
9
global variable.
10 universe = 1;
11 foo();
12 printf("%d\n", universe);
13
14 return 0;
15 }
8
1.3. Masking
1 int bar = 0; An identifier declared inside a
2 block masks or overshadows
3 void foo() {
4 bar = 1; // Refer to the
the same identifier declared
5 } // global "bar" outside the block.
6
7 int main(void) {
8 int bar = 2;
9 bar++; // Refer to the "bar" declared in main()
10 {
11 int bar = 3;
12 printf("%d\n", bar); // Refer to the "bar"
13 declared in the
14
15 // current block
16 }
17 bar--; // Refer to the "bar" declared in main()
return 0;
Note: You should avoid introducing identifiers that mask other identifiers. 9
}
1.4. Why you should not use global variables
1 #include <stdio.h> void fcn3() {
2 int universe = -9; double h;
3 void fcn() { fcn();
4 int f; h = universe = 9;
5 universe *= 3; fcn2();
6 f = 99; What’s the value }
7 } of f here? int main(void) {
8 void fcn2() { int m;
9 double g; universe = m = 10;
10 universe -= 40; fcn();
11 fcn(); fcn2();
12 g = universe; fcn3();
13 } fcn();
14 Can you tell the value of return 0;
15 universe here (right }
after calling fcn3())?
10
1.4. Why you should not use global variables
11
2. Address
• Identifiers are human friendly names to identify
variables or other entities (such as functions) in C.
• The computer, however, access variables via their
unique locations in the memory, i.e. their
addresses.
12
2. Address
• The operator & allow us to access the address of a
variable in C during run-time.
– Does that look familiar to you?
• We can also use %p to help us print out addresses
as a hexadecimal number.
e.g. int x = 0;
printf("%p\n", &x);
13
2. Address
1 #include <stdio.h>
2 You have just learned about
3 int x = 0;
4 scope and masking. Notice
5 void foo() { here we have three different x
6 printf("Address 2: %p\n", &x);
(green, orange and blue).
7 }
8 What do you expect the
9 int main(void) { output to be?
10 int x = 0;
11 printf("Address 1: %p\n", &x);
12 if (x == 0) { Also, have you tried running
13 int x = 10; the program multiple times?
14 foo();
15 printf("Address 3: %p\n", &x);
16 }
17 return 0;
18 }
Note: For illustration only. Avoid introducing identifiers that mask other identifiers in 14
real programs.
2.1. Address of Arrays
• We can also use the operator & to print out the
addresses of array elements.
• If you recall, an array in C was introduced to you as
a continuous block of memory. What will be their
address be like?
15
2.1. Addresses of Arrays
1 #include <stdio.h>
2 Possible output:
3 int main(void) {
4 int i, myArray[10] = {0}; 0x7fffa4d1ac60
5 for (i = 0; i < 10; i++) { 0x7fffa4d1ac64
6 printf("%p\n", &myArray[i]); 0x7fffa4d1ac68
7 } 0x7fffa4d1ac6c
0x7fffa4d1ac70
8 return 0;
0x7fffa4d1ac74
9 } 0x7fffa4d1ac78
10 Do you see a pattern in the 0x7fffa4d1ac7c
11 0x7fffa4d1ac80
output? 0x7fffa4d1ac84
12
13
14 The addresses will differ by 4
15 (in most systems). Why do you
16 think it's 4?
17
16
3. Storage Class
• The storage class of a variable determines how the
variable's storage (in the computer memory) are managed
during program execution.
17
3.1. The Storage Class auto
int main(void) int main(void)
{ {
int a, b, c; Equivalen auto int a, b, c;
double f; t auto double f;
... ...
} }
18
3.1. The Storage Class auto
20
3.2.1. Local static Variable
1 #include <stdio.h>
2
3 void foo() {
4 static int static_var = 0;
5 int auto_var = 0;
6 printf("static = %d, auto = %d\n", static_var, auto_var);
7 static_var++;
8 auto_var++;
9 }
10
11 int main(void) {
12 int i; static = 0, auto = 0
13 for (i = 0; i < 5; i++) static = 1, auto = 0
14 foo(); static = 2, auto = 0
15 static = 3, auto = 0
16 return 0; static = 4, auto = 0
17 }
21
3.2.1. Local static Variable
1 #include <stdio.h>
2
3 void foo() {
4 static int static_var = 0;
5 int auto_var = 0;
6 printf("static = %d, auto = %d\n", static_var, auto_var);
7 static_var++;
8 auto_var++; static_var is created and
9 } initialized once per program
10
execution. It can retain value
11 int main(void) {
12 int i;
between function calls.
13 for (i = 0; i < 5; i++)
14 foo(); auto_var is created, initialized,
15 and eventually destroyed in each call
16 return 0;
to foo().
17 }
22
Summary
23
Reading Assignment
• C: How to Program, 8th ed, Deitel and Deitel
• Chapter 5 C Functions
– Section 5.12: Storage Classes
– Section 5.13: Scope Rules
24