Download presentation

Presentation is loading. Please wait.

Published byFreddie Hull Modified over 2 years ago

1
C Module System C and Data Structures Baojian Hua bjhua@ustc.edu.cn

2
Software System is Large Practical software systems tend to be large and complex: Linux kernel consists of ~1000K LOC So the general principals in designing large (even small) software systems are: dividing into manageable smaller ones separating specification (interface) from code (implementation)

3
Module System Different styles of module systems in languages: ML signature and structure Java interface and class C header files (.h) and C files (.c) The next slides explain the details of the C module system via one example: Complex number

4
Complex Number // Recall the definition of complex number c: // c = x + yi, where x,y \in R, and i=sqrt(-1); // And some typical operations: // complex newComplex (double x, double y); // complex add (complex c1, complex c2); // complex sub (complex c1, complex c2); // complex mult (complex c1, complex c2); // complex distance (complex c1, complex c2); // complex modus (complex c1, complex c2); // complex divide (complex c1, complex c2);

5
Complex Number: Interface — Types // In file “complex.h”: #ifndef COMPLEX_H #define COMPLEX_H // note that “struct complex” is not given typedef struct complex *complex; complex newComplex (double x, double y); // other function prototypes are similar … #endif

6
Client Code // With this interface, we can write client code // that manipulate complex numbers. File “main.c”: #include “complex.h” int main () { complex c1, c2, c3; c1 = newComplex (3.0, 4.0); c2 = newComplex (7.0, 6.0); c3 = add (c1, c2); printComplex (c3); return 0; }

7
Client Code // The client code now compiles: $gcc –c –std=c99 –pedantic –Wall complex.h main.c // which produces main.o, which roughly looks // like: newComplex( … ) add( … ) printComplex( … ) main.o Require an implementation of complex.h

8
Complex Number: Implementation#1 — Types // In file “complex.c”: #include “complex.h” // We may choose to define complex type as: struct complex { double x; double y; }; // which stores the real and imaginary parts of // a complex number in fields x and y in a // structure.

9
Complex Number: Implementation#1 — Operations // With this type definition, the “newComplex” // function could be written as: complex newComplex (double x, double y) { complex c = malloc (sizeof(*c)); c->x = x; c->y = y; return c; } // To call function “malloc”, we must include the // header file “stdio.h” #include

10
Complex Number: Implementation#1 — Operations // function “add ()”: complex add (complex c1, complex c2) { complex c = malloc (sizeof(*c)); c->x = c1->x + c2->x; c->y = c1->y + c2->y; return c; } // Leave other functions as programming // assignments. See the course page.

11
Linking // Now compiles file “complex.c”: $gcc –c –std=c99 –pedantic –Wall complex.h complex.c // to produce file “complex.o”. newComplex( … ) add( … ) printComplex( … ) newComplex( … ) {} add( … ){} printComplex( … ) {} main.ocomplex.o Linking (simplified) a.out

12
Complex Number: Implementation#2 — Types // In file “comp2.c”: // Another definition of complex type: #include #include “complex.h” struct complex { double a[2]; }; // which stores the real and imaginary parts of // a complex number in array element a[0] and // a[1] separately.

13
Complex Number: Implementation#2 — Operations // With this type definition, the “newComplex” // function could be written as: complex newComplex (double x, double y) { complex c = malloc (sizeof(*c)); (c->a)[0] = x; (c->a)[1] = y; return c; }

14
Complex Number: Implementation#2 — Operations // function “add ()”: complex add (complex c1, complex c2) { complex c = malloc (sizeof(*c)); (c->a)[0] = (c1->a)[0] + (c2->a)[0]; (c->a)[1] = (c1->a)[1] + (c2->a)[1]; return c; } // Leave other functions as programming // assignments. See the course page.

15
Linking // Now compiles file “complex.c”: $gcc –c –std=c99 –pedantic –Wall complex.h comp2.c // to produce file “comp2.o”. newComplex( … ) add( … ) printComplex( … ) newComplex( … ) {} add( … ){} printComplex( … ) {} main.ocomp2.o Linking (simplified) a.out

16
Summary The many benefits of modularity: Reading the code: in small, separable pieces Testing the code: test each function separately Speeding up the code: focus only on the slow parts Extending the code: change only the relevant parts Compiling the code: compile each part separately

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google