Chapter 27 - Chapter 27 Chapter The C Programming Language...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 27 Chapter The C Programming Language Bjarne Stroustrup Dennis M. Ritchie Abstract Abstract This lecture gives you the briefest introduction to C This from a C++ point of view. If you need to use this language, read an introductory book (e.g. K&R). This lecture gives you a hint what to look for. lecture C is C++’s closest relative, and compatible in many is areas, so much of your C++ knowledge carries over. Stroustrup/Programming 2 Overview Overview C and C++ Function prototypes printf()/scanf() Arrays and strings Memory management Macros const C/C++ interoperability Stroustrup/Programming 3 dmr C and C++ and ken bwk bs doug … Both were “born” in the Computer Science Research Department of Both Bell Labs in Murray Hill, NJ Bell Stroustrup/Programming 4 Modern C and C++ are siblings Modern Stroustrup/Programming 5 C and C++ and In this talk, I use “C” to mean “ISO C89” That’s by far the most commonly used definition of C Source compatibility C is (almost) a subset of C++ Example of exception: sizeof('a') /* 4 in C and 1 in C++ */ Example */ Link compatibility C and C++ program fragments can be linked together in a single program Example of excepion: int f(int new, int class, int bool); /* ok in C */ Example int */ (Almost) all constructs that are both C and C++ have the same meaning (Almost) (semantics) in both languages (semantics) Classic C has mostly been replaced (though amazingly not completely) C99 is not yet widely used And very often are C++ was designed to be “as close as possible to C, but no closer” For ease of transition For co-existence Most incompatibilities are related to C++’s stricter type checking Stroustrup/Programming 6 C and C++ and Both defined/controlled by ISO standards committees Separate committees Unfortunately, leading to incompatibilities Many supported implementations in use Available on more platforms than any other languages Both primarily aimed at and are heavily used for hard system Both programming tasks, such as programming Operating systems kernels Device drivers Embedded systems Compilers Communications systems Stroustrup/Programming 7 C and C++ and Here we assume you know C++ and how to use it describe the differences between C and C++ describe how to program using the facilities offered by C Our ideal of programming and our techniques remain the same, but Our the tool available to express our ideas change the describe a few C “traps and pitfalls” don’t go into all the details from the book Compatibility details are important, but rarely interesting Stroustrup/Programming 8 C and C++ and C++ is a general-purpose programming language with C++ a bias towards systems programming that bias is a better C supports data abstraction supports object-oriented programming supports generic programming C: Functions and structs Functions struct Machine model (basic types and operations) Compilation and linkage model Stroustrup/Programming 9 Missing in C (from a C++ perspective) (from Classes and member functions Derived classes and virtual functions Use malloc()/free() Use malloc()/free() References Give each function a separate name new/delete Use error-codes, error-return values, etc. Function overloading Use macros Exceptions Use struct , global functions, and pointers to functions Use struct You can do OOP in C, but not cleanly, and why would you want to? You can do GP in C, but why would you want to? Templates and inline functions Use struct and global functions Use struct Use pointers const in constant expressions Use macros Stroustrup/Programming 10 Missing in C (from a C++ perspective) (from With no classes, templates, and exceptions, C can’t With provide most C++ standard library facilities provide Containers vector, map, set, string, etc. map Use arrays and pointers Use macros (rather than parameterization with types) STL algorithms Iostreams sort(), find(), copy(), … Not many alternatives use qsort() where you can use where Write your own, use 3rd party libraries Use stdio: printf(), getch(), etc. getch() etc. Regular expression Use a 3rd party library Stroustrup/Programming 11 C and C++ and Lots of useful code is written in C Very few language features are essential Emulate high-level programming techniques Compile in both languages to ensure consistency Use high compiler warning levels to catch type errors Use “lint” for large programs As directly supported by C++ but not C Write in the C subset of C++ In principle, you don’t need a high-level language, you could write In everything in assembler (but why would you want to do that?) everything A “lint” is a consistency checking program C and C++ are equally efficient If you think you see a difference, suspect differences in default If optimizer or linker Stroustrup/Programming settings optimizer 12 Functions Functions There can be only one function of a given name Function argument type checking is optional There are no references (and therefore no pass-by-reference) There are no member functions There are no inline functions (except in C99) There is an alternative function definition syntax Stroustrup/Programming 13 Function prototypes Function (function argument checking is optional) /* avoid these mistakes – use a compiler option that enforces C++ rules */ /* avoid */ int g(int); int h(); /* prototype – like C++ function declaration */ /* prototype */ /* not a prototype – the argument types are unspecified */ /* not */ int f(p,b) char* p; char b; { /* … */ } /* /* old style definition – not a prototype */ /* old */ int my_fct(int a, double d, char* p) /* new style definition – a prototype */ /* new */ { f(); /* ok by the compiler! But gives wrong/unexpected results */ /* ok */ f(d,p); /* ok by the compiler! But gives wrong/unexpected results */ /* ok */ h(d); /* ok by the compiler! But may give wrong/unexpected results */ /* ok */ ff(d); /* ok by the compiler! But may give wrong/unexpected results */ /* ok */ g(p); g(); } /* error: wrong type */ /* error: */ /* error: argument missing */ /* error: */ Stroustrup/Programming 14 printf() – many people’s favorite C function many Format string /* no iostreams – use stdio */ /* no */ #include<stdio.h> /* defines int printf(const char* format, …); */ */ int main(void) { printf("Hello, world\n"); return 0; } Arguments to be formatted void f(double d, char* s, int i, char ch) { printf("double %g string %s int %i char %c\n", d, s, i, ch); printf("goof %s\n", i); /* uncaught error */ /* uncaught */ } Format strings Formatting characters Stroustrup/Programming 15 scanf() and friends scanf() /* the most popular input functions from <stdio.h>: */ /* the int i = getchar(); /* note int, not char; /* note getchar() returns EOF when it reaches end of file */ returns */ p = gets(); /* read '\n' terminated line into char array pointed to by p */ /* read terminated array */ void f(int* pi, char* pc, double* pd, char* ps) { /* read into variables whose addresses are passed as pointers: */ */ scanf("%i %c %g %s", pi, pc, pd, ps); /* %s skips initial whitespace and is terminated by whitespace */ /* skips } int i; char c; double d; char s[100]; f(&i, &c, &d, s); /* call to assign to i, c, d, and s */ int and */ Don’t ever use gets() or scanf("%s")! Don’t ever gets() scanf("%s") Consider them poisoned They are the source of many security violations They many An overflow is easily arranged and easily exploitable Use getchar() Use getchar() Stroustrup/Programming 16 printf() and scanf() are not type safe printf() scanf() double d = 0; int s = 0; printf("d: %d , s: %s\n", d, s); /* compiles and runs /* compiles the result might surprise you */ */ “s” for “string” “d” for “decimal”, not “double” Though error-prone, printf() is convenient for built-in types Though is printf() formats are not extensible to user-defined types printf() formats E.g. no %M for My_type values E.g. %M My_type Beware: a printf () with a user-supplied format string is a cracker tool Beware: with Stroustrup/Programming 17 Arrays and pointers Arrays Defined almost exactly as in C++ In C, you have to use them essentially all the time because there is no vector, map, string, etc. because vector, Remember An array doesn’t know how long it is There is no array assignment use memcpy() use memcpy() A C-style string is a zero-terminated array Stroustrup/Programming 18 C-style strings C-style In C a string (called a C-string or a C-style string in C++ In literature) is a zero-terminated array of characters literature) char* p = "asdf"; char s[ ] = "asdf"; 'a' p: s: 'a' 's' 's' 'd' 'd' Stroustrup/Programming 'f' 'f' 0 0 19 C-style strings C-style Comparing strings #include <string.h> if (s1 = = s2) { /* do s1 and s2 point to the same array? and point (typically not what you want) */ */ } if (strcmp(s1,s2) = = 0) { /* do s1 and s2 hold the same characters? */ if and */ } Finding the lengths of a string int lgt = strlen(s); /* note: goes through the string at run time /* note: looking for the terminating 0 */ */ Copying strings strcpy(s1,s2); /* copy characters from s2 into s1 /* copy into be sure that s1 can hold that many characters */ be */ Stroustrup/Programming 20 C-style strings C-style The string copy function strcpy() is the archetypical The strcpy() C function (found in the ISO C standard library) function Unless you understand the implementation below, Unless don’t claim to understand C: don’t char* strcpy(char *p, const char *q) { while (*p++ = *q++); while return p; return } For an explanation see for example K&R or TC++PL Stroustrup/Programming 21 Standard function libraries Standard <stdio.h> <string.h> <string.h> <ctype.c> <ctype.c> <stdlib.h> <stdlib.h> <math.h> <math.h> printf(), scanf(), etc. strcmp(), etc. strcmp() isspace(), etc. isspace() etc. malloc(), etc. malloc() etc. sqrt(), etc. sqrt() etc. Warning: By default, Microsoft tries to force you to use safer, Warning: but non-standard, alternatives to the unsafe C standard library functions functions Stroustrup/Programming 22 Free store: malloc()/free() Free #include<stdlib.h> void f(int n) { /* malloc() takes a number of bytes as its argument */ /* */ int* p = (int*)malloc(sizeof(int)*n); /* allocate an array of n ints */ /* int */ /* … */ /* free(p); /* free() returns memory allocated by malloc() to free store */ /* returns */ } Stroustrup/Programming 23 Free store: malloc()/free() Free Little compile-time checking /* malloc() returns a void*. You can leave out the cast of malloc(), but don’t malloc() */ */ double* p = malloc(sizeof(int)*n); /* probably a bug */ /* */ Little run-time checking int* q = malloc(sizeof(int)*m); /* m ints */ int* int */ for (int i=0; i<n; ++i) init(q[i]); No initialization/cleanup malloc() doesn’t call constructors malloc() doesn’t free() doesn’t call destructors Write and remember to use your own init() and cleanup() Write cleanup() There is no way to ensure automatic cleanup Don’t use malloc()/free() in C++ programs in new/delete are as fast and almost always better new/delete are Stroustrup/Programming 24 Uncast malloc() malloc() The major C/C++ incompatibility in real-world code Not-type safe Historically a pre-standard C compatibility hack/feature Always controversial Unnecessarily so IMO void* alloc(size_t x); /* allocate x bytes allocate in C, but not in C++, void* converts to any T* */ */ void f (int n) { int* p = alloc(n*sizeof(int)); /* ok in C; error in C++ */ int* /* */ int* q = (int*)alloc(n*sizeof(int)); /* ok in C and C++ */ int* /* */ /* … */ /* */ } Stroustrup/Programming 25 void* void* Why does void* convert to T* in C but not in C++? C needs it to save you from casting the result of malloc() needs malloc() C++ does not: use new C++ new Why is a void* to T* conversion not type safe? Why void* T* void f() { char i = 0; char j = 0; char* p = &i; void* q = p; int* pp = q; *pp = -1; } /* unsafe, legal C; error in C++ */ /* unsafe, */ /* overwrite memory starting at &i */ overwrite */ Stroustrup/Programming 26 Comments Comments // comments were introduced by Bjarne Stroustrup into C++ from C’s ancestor BCPL when he got really fed up with typing /* … */ comments /* */ // comments are accepted by most C dialects including the new ISO standard C (C99) new Stroustrup/Programming 27 const const // in C, a const is never a compile time constant // in const int max = 30; const const int x; // const not initialized: ok in C (error in C++) // not void f(int v) { int a1[max]; // error: array bound not a constant (max is not a constant!) // error: max is int a2[x]; // error: array bound not a constant (here you see why) // error: switch (v) { case 1: // … // case max: // error: case label not a constant // error: // … // } Stroustrup/Programming 28 } Instead of const use macros const #define max 30 void f(int v) { int a1[max]; // ok // ok switch (v) { case 1: // … // case max: // ok // ok // … // } } Stroustrup/Programming 29 Beware of macros Beware #include "my_header.h" // … // int max(int a, int b) { return a>=b?a:b; } // error: “obscure error message” // error: As it happened my_header.h contained the macro max from the previous As my_header.h max slide so what the compiler saw was slide int 30(int a, int b) { return a>=b?a:b; } No wonder it complained! There are tens of thousands of macros in popular header files. Always define macros with ALL_CAPS names, e.g. Always ALL_CAPS #define MY_MAX 30 and never give anything but a macro an ALL_CAPS name and ALL_CAPS Unfortunately, not everyone obeys the ALL_CAPS convention Stroustrup/Programming 30 C/C++ interoperability C/C++ Works because of shared linkage model Works because a shared model for simple objects built-in types and structs/classes Optimal/Efficient No behind-the-scenes reformatting/conversions Stroustrup/Programming 31 Calling C from C++ Calling Use extern "C" to tell the C++ compiler to use C calling Use extern conventions conventions // calling C function from C++: // calling extern "C" double sqrt(double); extern // link as a C function link void my_c_plus_plus_fct() void { double sr = sqrt(2); // … // } Stroustrup/Programming 32 Calling C++ from C Calling No special action is needed from the C compiler /* call C++ function from C: */ /* */ int call_f(S* p, int i); /* call f for object pointed to by p with argument i */ */ struct S* make_S(int x, const char* p); /* make S( x,p) on the free store */ struct */ void my_c_fct(int i) void { /* … * / /* struct S* p = make_S(17, "foo"); int x = call_f(p,i); /* … */ } Stroustrup/Programming 33 Word counting example (C++ version) (C++ #include<map> #include<string> #include<iostream> using namespace std; int main() { map<string,int> m; string s; while (cin>>s) m[s]++; // use getline() if you really want lines // if for(map<string,int>::iterator p = m.begin(); p!=m.end(); ++p) cout << p->first << " : " << p->second << "\n"; } Stroustrup/Programming 34 Word counting example (C version) (C // word_freq.c // // Walter C. Daugherity #include <stdio.h> #include <stdlib.h> #include #include <string.h> #define MAX_WORDS 1000 /* max unique words to count */ #define */ #define MAX_WORD_LENGTH 100 #define STR(s) #s #define XSTR(s) STR(s) /* macros for scanf format */ /* */ typedef struct record{ char word[MAX_WORD_LENGTH + 1]; char int count; } record; Stroustrup/Programming 35 Word counting example (C version) (C int main() { // … read words and build table … // read qsort(table, num_words, sizeof(record), strcmp); qsort(table, for(iter=0; iter<num_words; ++iter) for(iter=0; printf("%s %d\n",table[iter].word,table[iter].count); return EXIT_SUCCESS; return } Stroustrup/Programming 36 Word counting example (most of main) (most record table[MAX_WORDS + 1]; int num_words = 0; char word[MAX_WORD_LENGTH + 1]; int iter; while(scanf("%" XSTR(MAX_WORD_LENGTH) "s", word) != EOF) { for(iter = 0; iter < num_words && strcmp(table[iter].word, word); ++iter); for(iter if(iter == num_words) { if(iter strncpy(table[num_words].word, word, MAX_WORD_LENGTH + 1); strncpy(table[num_words].word, table[num_words++].count = 1; table[num_words++].count } else table[iter].count++; else if(num_words > MAX_WORDS){ if(num_words printf("table is full\n"); printf("table return EXIT_FAILURE; return } } Stroustrup/Programming 37 Word counting example (C version) (C Comments In (some) colloquial C style (not written by BS) It’s so long and complicated! (my first reaction – BS) See, you don’t need any fancy and complicated language features!!! See, (not my comment – BS) (not IMHO not a very good problem for using C It’s also C++ except that in C++, the argument to qsort() should be It’s cast to its proper type: cast Not an atypical application, but not low-level systems programming (int (*)(const void*, const void*))strcmp What are those macros doing? What Maxes out at MAX_WORD words Maxes MAX_WORD Doesn’t handle words longer than MAX_WORD_LENGTH Doesn’t MAX_WORD_LENGTH First reads and then sorts Inherently slower than the colloquial C++ version (which uses a map) Inherently map Stroustrup/Programming 38 More information More Kernighan & Ritchie: The C Programming Language Stroustrup: TC++PL, Appendix B: Compatibility C/C++ incompatibilities, on my home pages Stroustrup: Learning Standard C++ as a New Language. The classic Style and technique comparisons Lots of book reviews: Stroustrup/Programming 39 ...
View Full Document

This note was uploaded on 02/18/2012 for the course CSCE 121 taught by Professor Walter daugherity during the Fall '09 term at Texas A&M.

Ask a homework question - tutors are online