Upload
mikaia
View
34
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Chapter 27 The C Programming Language. Bjarne Stroustrup www.stroustrup.com/Programming. Dennis M. Ritchie. Overview. C and C++ Function prototypes printf ()/ scanf () Arrays and strings Memory management Macros const C/C++ interoperability. C and C++. dmr ken bwk bs doug …. - PowerPoint PPT Presentation
Citation preview
Chapter 27Chapter 27The C Programming LanguageThe C Programming Language
Bjarne StroustrupBjarne Stroustrupwww.stroustrup.com/Programmingwww.stroustrup.com/Programming
Dennis M. Ritchie
OverviewOverview C and C++C and C++ Function prototypesFunction prototypes printf()/scanf()printf()/scanf() Arrays and stringsArrays and strings Memory managementMemory management MacrosMacros constconst C/C++ interoperabilityC/C++ interoperability
33Stroustrup/ProgrammingStroustrup/Programming
C and C++C and C++
Both were “born” in the Computer Science Research Department of Both were “born” in the Computer Science Research Department of Bell Labs in Murray Hill, NJBell Labs in Murray Hill, NJ
44
dmr
ken
bwk
bs
doug
…
Stroustrup/ProgrammingStroustrup/Programming
Modern C and C++ are siblingsModern C and C++ are siblings
Stroustrup/ProgrammingStroustrup/Programming 55
C and C++C and C++ In this talk, I use “C” to mean “ISO C89”In this talk, I use “C” to mean “ISO C89”
That’s by far the most commonly used definition of CThat’s by far the most commonly used definition of C Classic C has mostly been replaced (though amazingly not completely)Classic C has mostly been replaced (though amazingly not completely) C99 is not yet widely usedC99 is not yet widely used
Source compatibilitySource compatibility C is (almost) a subset of C++C is (almost) a subset of C++
Example of excepion: Example of excepion: int f(int new, int class, int bool);int f(int new, int class, int bool); /* /* ok in C ok in C */*/ (Almost) all constructs that are both C and C++ have the same meaning (Almost) all constructs that are both C and C++ have the same meaning
(semantics) in both languages(semantics) in both languages Example of exception: Example of exception: sizeof('a') /* sizeof('a') /* 4 in C and 1 in C++ 4 in C and 1 in C++ */*/
Link compatibilityLink compatibility C and C++ program fragments can be linked together in a single programC and C++ program fragments can be linked together in a single program
And very often areAnd very often are C++ was designed to be “as close as possible to C, but no closer”C++ was designed to be “as close as possible to C, but no closer”
For ease of transitionFor ease of transition For co-existenceFor co-existence Most incompatibilities are related to C++’s stricter type checkingMost incompatibilities are related to C++’s stricter type checking
66Stroustrup/ProgrammingStroustrup/Programming
C and C++C and C++ Both defined/controlled by ISO standards committeesBoth defined/controlled by ISO standards committees
Separate committeesSeparate committees Unfortunately, leading to incompatibilitiesUnfortunately, leading to incompatibilities
Many supported implementations in useMany supported implementations in use Available on more platforms than any other languagesAvailable on more platforms than any other languages
Both primarily aimed at and are heavily used for hard system Both primarily aimed at and are heavily used for hard system programming tasks, such asprogramming tasks, such as Operating systems kernelsOperating systems kernels Device driversDevice drivers Embedded systemsEmbedded systems CompilersCompilers Communications systemsCommunications systems
77Stroustrup/ProgrammingStroustrup/Programming
C and C++C and C++ Here weHere we
assume you know C++ and how to use itassume you know C++ and how to use it describe the differences between C and C++describe the differences between C and C++ describe how to program using the facilities offered by Cdescribe how to program using the facilities offered by C
Our ideal of programming and our techniques remain the same, but Our ideal of programming and our techniques remain the same, but the tool available to express our ideas changethe tool available to express our ideas change
describe a few C “traps and pitfalls”describe a few C “traps and pitfalls” don’t go into all the details from the bookdon’t go into all the details from the book
Compatibility details are important, but rarely interestingCompatibility details are important, but rarely interesting
Stroustrup/ProgrammingStroustrup/Programming 88
C and C++C and C++
C++ is a general-purpose programming language C++ is a general-purpose programming language with a bias towards systems programming thatwith a bias towards systems programming that is a better Cis a better C supports data abstractionsupports data abstraction supports object-oriented programmingsupports object-oriented programming supports generic programmingsupports generic programming
99Stroustrup/ProgrammingStroustrup/Programming
C:C: Functions and Functions and structstructss Machine model (basic types and operations)Machine model (basic types and operations) Compilation and linkage modelCompilation and linkage model
Missing in C Missing in C (from a C++ perspective)(from a C++ perspective)
Classes and member functionsClasses and member functions Use Use structstruct and global functions and global functions
Derived classes and virtual functionsDerived classes and virtual functions Use Use structstruct , global functions, and pointers to functions , global functions, and pointers to functions You can do OOP in C, but not cleanly, and why would you want to?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?You can do GP in C, but why would you want to?
Templates and inline functionsTemplates and inline functions Use macrosUse macros
ExceptionsExceptions Use error-codes, error-return values, etc.Use error-codes, error-return values, etc.
Function overloadingFunction overloading Give each function a separate nameGive each function a separate name
new/deletenew/delete Use Use malloc()/free()malloc()/free()
ReferencesReferences Use pointersUse pointers
constconst in constant expressions in constant expressions Use macrosUse macros
1010Stroustrup/ProgrammingStroustrup/Programming
Missing in C Missing in C (from a C++ perspective)(from a C++ perspective)
With no classes, templates, and exceptions, C can’t With no classes, templates, and exceptions, C can’t provide most C++ standard library facilitiesprovide most C++ standard library facilities ContainersContainers
vectorvector, , mapmap,, set set,, string string, etc., etc. Use arrays and pointersUse arrays and pointers Use macros (rather than parameterization with types)Use macros (rather than parameterization with types)
STL algorithmsSTL algorithms sort()sort(),, find() find(),, copy() copy(),, …… Not many alternativesNot many alternatives use use qsort() qsort() where you canwhere you can Write your own, use 3Write your own, use 3rdrd party libraries party libraries
IostreamsIostreams Use stdio:Use stdio: printf() printf(), , getch()getch(),, etc.etc.
Regular expressionRegular expression Use a 3Use a 3rdrd party library party library
1111Stroustrup/ProgrammingStroustrup/Programming
C and C++C and C++ Lots of useful code is written in CLots of useful code is written in C
Very few language features are essentialVery few language features are essential In principle, you don’t need a high-level language, you could write everything in In principle, you don’t need a high-level language, you could write everything in
assembler (but why would you want to do that?)assembler (but why would you want to do that?)
Emulate high-level programming techniquesEmulate high-level programming techniques As directly supported by C++ but not CAs directly supported by C++ but not C
Write in the C subset of C++Write in the C subset of C++ Compile in both languages to ensure consistencyCompile in both languages to ensure consistency
Use high compiler warning levels to catch type errorsUse high compiler warning levels to catch type errors Use “lint” for large programsUse “lint” for large programs
A “lint” is a consistency checking programA “lint” is a consistency checking program
C and C++ are equally efficientC and C++ are equally efficient If you think you see a difference, suspect differences in default optimizer or If you think you see a difference, suspect differences in default optimizer or
linker settingslinker settings
Stroustrup/ProgrammingStroustrup/Programming 1212
FunctionsFunctions There can be only one function of a given nameThere can be only one function of a given name Function argument type checking is optionalFunction argument type checking is optional There are no references (and therefore no pass-by-reference)There are no references (and therefore no pass-by-reference) There are no member functionsThere are no member functions There are no inline functions (except in C99)There are no inline functions (except in C99) There is an alternative function definition syntaxThere is an alternative function definition syntax
Stroustrup/ProgrammingStroustrup/Programming 1313
Function prototypesFunction prototypes(function argument checking is optional)(function argument checking is optional)
/* /* avoid these mistakes – use a compiler option that enforces C++ rulesavoid these mistakes – use a compiler option that enforces C++ rules */*/
int g(int);int g(int); /* /* prototype – like C++ function declarationprototype – like C++ function declaration */*/int h();int h(); /* /* not a prototype – the argument types are unspecifiednot a prototype – the argument types are unspecified */*/
int f(p,b) char* p; char b;int f(p,b) char* p; char b; /* /* old style definition – not a prototypeold style definition – not a prototype */*/{ /* { /* …… */ } */ }
int my_fct(int a, double d, char* p)int my_fct(int a, double d, char* p) /* /* new style definition – a prototypenew style definition – a prototype */*/{{
f();f(); /* /* ok by the compiler! But gives wrong/unexpected resultsok by the compiler! But gives wrong/unexpected results */*/f(d,p);f(d,p); /* /* ok by the compiler! But gives wrong/unexpected resultsok by the compiler! But gives wrong/unexpected results */*/h(d);h(d); /* /* ok by the compiler! But may give wrong/unexpected resultsok by the compiler! But may give wrong/unexpected results */*/ff(d);ff(d); /* /* ok by the compiler! But may give wrong/unexpected resultsok by the compiler! But may give wrong/unexpected results */*/
g(p);g(p); /* /* error: wrong typeerror: wrong type */*/g();g(); /* /* error: argument missingerror: argument missing */*/
}}1414Stroustrup/ProgrammingStroustrup/Programming
printf() printf() – many people’s favorite C function– many people’s favorite C function
/* /* no iostreams – use stdiono iostreams – use stdio */*/
#include<stdio.h>#include<stdio.h> /* /* defines defines int printf(const char* format, …); int printf(const char* format, …); */*/
int main(void)int main(void){{
printf("Hello, world\n");printf("Hello, world\n");return 0;return 0;
}}
void f(double d, char* s, int i, char ch)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("double %g string %s int %i char %c\n", d, s, i, ch);printf("goof %s\n", i);printf("goof %s\n", i); /* /* uncaught erroruncaught error */*/
}}
1515
Format stringsFormatting characters
Arguments to be formatted
Format string
Stroustrup/ProgrammingStroustrup/Programming
scanf()scanf() and friends and friends/* /* the most popular input functions fromthe most popular input functions from <stdio.h> <stdio.h>:: */ */int i = getchar();int i = getchar(); /* /* notenote int int, not, not char char;;
getchar() getchar() returnsreturns EOF EOF when it reaches end of file when it reaches end of file */*/p = gets();p = gets(); /* /* read 'read '\n\n'' terminated line intoterminated line into char char array pointed to byarray pointed to by p p */*/
void f(int* pi, char* pc, double* pd, char* ps)void f(int* pi, char* pc, double* pd, char* ps){{ /*/* read into variables whose addresses are passed as pointers: read into variables whose addresses are passed as pointers: */*/
scanf("%i %c %g %s", pi, pc, pd, ps);scanf("%i %c %g %s", pi, pc, pd, ps);/* /* %s %s skips initial whitespace and is terminated by whitespaceskips initial whitespace and is terminated by whitespace */ */
}}int i; char c; double d; char s[100]; f(&i, &c, &d, s); /* int i; char c; double d; char s[100]; f(&i, &c, &d, s); /* call to assign to call to assign to ii,, c c,, d d, and , and s s */*/
Don’t Don’t everever use use gets()gets() or or scanf("%s")scanf("%s")!! Consider them poisonedConsider them poisoned They are the source of They are the source of manymany security violations security violations An overflow is easily arranged and easily exploitableAn overflow is easily arranged and easily exploitable Use Use getchar()getchar()
1616Stroustrup/ProgrammingStroustrup/Programming
printf()printf() and and scanf()scanf() are not type safe are not type safe
double d = 0;double d = 0;
int s = 0;int s = 0;
printf("d: %d , s: %s\n", d, s);printf("d: %d , s: %s\n", d, s); /* /* compiles and runscompiles and runs
the result might surprise you the result might surprise you */*/
1717
“d” for “decimal”, not “double”
“s” for “string”
Stroustrup/ProgrammingStroustrup/Programming
Though error-prone, Though error-prone, printf() printf() is convenient for built-in typesis convenient for built-in types printf() printf() formats are not extensible to user-defined typesformats are not extensible to user-defined types
E.g. no E.g. no %M%M for for My_typeMy_type values values Beware: a Beware: a printf () printf () with a user-supplied format string is a cracker toolwith a user-supplied format string is a cracker tool
Arrays and pointersArrays and pointers Defined almost exactly as in C++Defined almost exactly as in C++ In C, you have to use them essentially all the timeIn C, you have to use them essentially all the time
because there is no because there is no vector, map, stringvector, map, string, etc., etc.
RememberRemember An array doesn’t know how long it isAn array doesn’t know how long it is There is no array assignmentThere is no array assignment
use use memcpy()memcpy()
A C-style string is a zero-terminated arrayA C-style string is a zero-terminated array
1818Stroustrup/ProgrammingStroustrup/Programming
C-style stringsC-style strings
In C a string (called a C-string or a C-style string in C++ In C a string (called a C-string or a C-style string in C++ literature) is a zero-terminated array of charactersliterature) is a zero-terminated array of characterschar* p = "asdf";char* p = "asdf";
char s[ ] = "asdf";char s[ ] = "asdf";
1919
'a' 's' 'f''d' 0p:
'a' 's' 'f''d' 0s:
Stroustrup/ProgrammingStroustrup/Programming
C-style stringsC-style strings Comparing stringsComparing strings
#include <string.h>#include <string.h>if (s1 = = s2) {if (s1 = = s2) { /*/* do do s1 s1 andand s2 s2 point to the same array?point to the same array?
(typically not what you want) (typically not what you want) */*/}}
if (strcmp(s1,s2) = = 0) { if (strcmp(s1,s2) = = 0) { /* /* do do s1 s1 andand s2 s2 hold the same characters? hold the same characters? */*/}}
Finding the lengths of a stringFinding the lengths of a stringint lgt = strlen(s);int lgt = strlen(s); /* /* note: goes through the string at run timenote: goes through the string at run time
looking for the terminating 0 looking for the terminating 0 */*/
Copying stringsCopying stringsstrcpy(s1,s2);strcpy(s1,s2); /* /* copy characters fromcopy characters from s2 s2 intointo s1 s1
be sure thatbe sure that s1 s1 can hold that many can hold that many characters characters */*/
2020Stroustrup/ProgrammingStroustrup/Programming
C-style stringsC-style strings The string copy function The string copy function strcpy()strcpy() is the archetypical C is the archetypical C
function (found in the ISO C standard library)function (found in the ISO C standard library) Unless you understand the implementation below, don’t Unless you understand the implementation below, don’t
claim to understand C:claim to understand C:
char* strcpy(char *p, const char *q)char* strcpy(char *p, const char *q)
{{
while (*p++ = *q++);while (*p++ = *q++);
return p;return p;
}}
For an explanation see for example K&R or TC++PLFor an explanation see for example K&R or TC++PL
Stroustrup/ProgrammingStroustrup/Programming 2121
Standard function librariesStandard function libraries <stdio.h><stdio.h> printf() printf(),, scanf() scanf(), etc., etc. <string.h> <string.h> strcmp()strcmp(), etc., etc. <ctype.c> <ctype.c> isspace()isspace(),, etc.etc. <stdlib.h> <stdlib.h> malloc()malloc(),, etc.etc. <math.h> <math.h> sqrt()sqrt(),, etc.etc.
Warning: By default, Microsoft tries to force you to use safer, Warning: By default, Microsoft tries to force you to use safer, but non-standard, alternatives to the unsafe C standard library but non-standard, alternatives to the unsafe C standard library functionsfunctions
2222Stroustrup/ProgrammingStroustrup/Programming
Free store: malloc()/free()Free store: malloc()/free()
#include<stdlib.h>#include<stdlib.h>
void f(int n) {void f(int n) {/* /* malloc() malloc() takes a number of bytes as its argument takes a number of bytes as its argument */*/int* p = (int*)malloc(sizeof(int)*n);int* p = (int*)malloc(sizeof(int)*n); /* /* allocate an array of allocate an array of n intn ints s */*//* /* …… */ */free(p);free(p); /* /* free() free() returns memory allocated byreturns memory allocated by malloc() malloc() to free store to free store */*/
}}
2323Stroustrup/ProgrammingStroustrup/Programming
Free store: malloc()/free()Free store: malloc()/free() Little compile-time checkingLittle compile-time checking
/*/* malloc()malloc() returns a returns a void*. void*. You can leave out the cast of malloc(), but don’t You can leave out the cast of malloc(), but don’t */*/
double* p = malloc(sizeof(int)*n);double* p = malloc(sizeof(int)*n); /* /* probably a bug probably a bug */*/
Little run-time checkingLittle run-time checkingint* q = malloc(sizeof(int)*m); /* int* q = malloc(sizeof(int)*m); /* m intm ints s */*/for (int i=0; i<n; ++i) init(q[i]);for (int i=0; i<n; ++i) init(q[i]);
No initialization/cleanupNo initialization/cleanup malloc() malloc() doesn’t call constructorsdoesn’t call constructors free()free() doesn’t call destructors doesn’t call destructors Write and remember to use your own Write and remember to use your own init() init() and and cleanup()cleanup()
There is no way to ensure automatic cleanupThere is no way to ensure automatic cleanup Don’t useDon’t use malloc()/free() malloc()/free() in C++ programsin C++ programs
new/delete new/delete are as fast and almost always betterare as fast and almost always better 2424Stroustrup/ProgrammingStroustrup/Programming
Uncast Uncast malloc()malloc() The major C/C++ incompatibility in real-world codeThe major C/C++ incompatibility in real-world code
Not-type safeNot-type safe Historically a pre-standard C compatibility hack/featureHistorically a pre-standard C compatibility hack/feature
Always controversialAlways controversial Unnecessarily so IMOUnnecessarily so IMO
void* alloc(size_t x);void* alloc(size_t x); /*/* allocate x bytesallocate x bytes
in C, but not in C++, in C, but not in C++, void* void* converts to any converts to any T* T* */*/
void f (int n)void f (int n)
{{
int* p = alloc(n*sizeof(int)); int* p = alloc(n*sizeof(int)); /*/* ok in C; error in C++ ok in C; error in C++ */*/
int* q = (int*)alloc(n*sizeof(int)); int* q = (int*)alloc(n*sizeof(int)); /*/* ok in C and C++ ok in C and C++ */*/
/* /* … */… */
}}
Stroustrup/ProgrammingStroustrup/Programming 2525
void*void* Why does void* convert to T* in C but not in C++?Why does void* convert to T* in C but not in C++?
C needs it to save you from casting the result of C needs it to save you from casting the result of malloc()malloc() C++ does not: use C++ does not: use newnew
Why is a Why is a void*void* to to T*T* conversion not type safe? conversion not type safe?void f()void f()
{{
char i = 0;char i = 0;
char j = 0;char j = 0;
char* p = &i;char* p = &i;
void* q = p;void* q = p;
int* pp = q;int* pp = q; /* /* unsafe, legal C; error in C++unsafe, legal C; error in C++ */*/
*pp = -1;*pp = -1; /*/* overwrite memory starting at &ioverwrite memory starting at &i */*/
}}
Stroustrup/ProgrammingStroustrup/Programming 2626
CommentsComments //// comments were introduced by Bjarne Stroustrup into C++ comments were introduced by Bjarne Stroustrup into C++
from C’s ancestor BCPL when he got really fed up with typing from C’s ancestor BCPL when he got really fed up with typing /*/* … … */*/ comments comments
//// comments are accepted by most C dialects including the new comments are accepted by most C dialects including the new ISO standard C (C99)ISO standard C (C99)
2727Stroustrup/ProgrammingStroustrup/Programming
constconst
// // in C, ain C, a const const is never a compile time constant is never a compile time constant
const int max = 30;const int max = 30;
const int x;const int x; // // const const not initialized: ok in C (error in C++)not initialized: ok in C (error in C++)
void f(int v)void f(int v)
{{
int a1[max];int a1[max]; // // error: array bound not a constant (error: array bound not a constant (max max is not a constant!)is not a constant!)
int a2[x];int a2[x]; // // error: array bound not a constanterror: array bound not a constant ( (here you see why)here you see why)
switch (v) {switch (v) {
case 1:case 1:
// // ……
case max:case max: // // error: case label not a constanterror: case label not a constant
// // ……
}}
}}2828Stroustrup/ProgrammingStroustrup/Programming
Instead of Instead of constconst use macros use macros#define max 30#define max 30
void f(int v)void f(int v)
{{
int a1[max];int a1[max]; // // okok
switch (v) {switch (v) {
case 1:case 1:
// // ……
case max:case max: // // okok
// // ……
}}
}}
2929Stroustrup/ProgrammingStroustrup/Programming
Beware of macrosBeware of macros#include "my_header.h"#include "my_header.h"// // ……int max(int a, int b) { return a>=b?a:b; }int max(int a, int b) { return a>=b?a:b; } // // error: “obscure error error: “obscure error
message”message”
As it happened As it happened my_header.hmy_header.h contained the macro contained the macro maxmax from the previous from the previous slide so what the compiler saw wasslide so what the compiler saw was
int 30(int a, int b) { return a>=b?a:b; }int 30(int a, int b) { return a>=b?a:b; }
No wonder it complained!No wonder it complained! There are tens of thousands of macros in popular header files.There are tens of thousands of macros in popular header files. Always define macros with Always define macros with ALL_CAPSALL_CAPS names, e.g. names, e.g.
#define MY_MAX 30#define MY_MAX 30and never give anything but a macro an and never give anything but a macro an ALL_CAPSALL_CAPS name name
Unfortunately, not everyone obeys the ALL_CAPS conventionUnfortunately, not everyone obeys the ALL_CAPS convention
3030Stroustrup/ProgrammingStroustrup/Programming
C/C++ interoperabilityC/C++ interoperability Works because of shared linkage modelWorks because of shared linkage model Works because a shared model for simple objectsWorks because a shared model for simple objects
built-in types and structs/classesbuilt-in types and structs/classes Optimal/EfficientOptimal/Efficient
No behind-the-scenes reformatting/conversionsNo behind-the-scenes reformatting/conversions
Stroustrup/ProgrammingStroustrup/Programming 3131
Calling C from C++Calling C from C++ Use Use extern "C"extern "C" to tell the C++ compiler to use C calling to tell the C++ compiler to use C calling
conventionsconventions
// // calling C function from C++:calling C function from C++:
extern "C" double sqrt(double);extern "C" double sqrt(double); //// link as a C functionlink as a C function
void my_c_plus_plus_fct()void my_c_plus_plus_fct()
{{
double sr = sqrt(2);double sr = sqrt(2);
// // ……
}}
Stroustrup/ProgrammingStroustrup/Programming 3232
Calling C++ from CCalling C++ from C No special action is needed from the C compilerNo special action is needed from the C compiler
/* /* call C++ function from C: call C++ function from C: */*/
int call_f(S* p, int i); int call_f(S* p, int i); /* call f for object pointed to by p with argument i /* call f for object pointed to by p with argument i */*/
struct S* make_S(int x, const char* p); /* struct S* make_S(int x, const char* p); /* make S( x,p) on the free store make S( x,p) on the free store */*/
void my_c_fct(int i)void my_c_fct(int i)
{{
/* /* …… */ */
struct S* p = make_S(17, "foo");struct S* p = make_S(17, "foo");
int x = call_f(p,i);int x = call_f(p,i);
/*/* …… */ */
}}
Stroustrup/ProgrammingStroustrup/Programming 3333
Word counting example Word counting example (C++ version)(C++ version)
#include<map>#include<map>#include<string>#include<string>#include<iostream>#include<iostream>using namespace std;using namespace std;
int main()int main(){{
map<string,int> m;map<string,int> m;string s;string s;while (cin>>s) m[s]++;while (cin>>s) m[s]++; // // use use getline() getline() if you really want linesif you really want linesfor(map<string,int>::iterator p = m.begin(); p!=m.end(); ++p)for(map<string,int>::iterator p = m.begin(); p!=m.end(); ++p)
cout << p->first << " : " << p->second << "\n";cout << p->first << " : " << p->second << "\n";}}
3434Stroustrup/ProgrammingStroustrup/Programming
Word counting example Word counting example (C version)(C version)// // word_freq.c word_freq.c
// // Walter C. Daugherity Walter C. Daugherity
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>#include <stdlib.h>
#include <string.h> #include <string.h>
#define MAX_WORDS 1000 /*#define MAX_WORDS 1000 /* max unique words to count max unique words to count */*/
#define MAX_WORD_LENGTH 100#define MAX_WORD_LENGTH 100
#define STR(s) #s#define STR(s) #s /* /* macros for scanf format macros for scanf format */*/
#define XSTR(s) STR(s)#define XSTR(s) STR(s)
typedef struct record{typedef struct record{
char word[MAX_WORD_LENGTH + 1];char word[MAX_WORD_LENGTH + 1];
int count;int count;
} record;} record;
3535Stroustrup/ProgrammingStroustrup/Programming
Word counting example Word counting example (C version)(C version)
int main()int main()
{{
// // … read words and build table …… read words and build table …
qsort(table, num_words, sizeof(record), strcmp);qsort(table, num_words, sizeof(record), strcmp);
for(iter=0; iter<num_words; ++iter)for(iter=0; iter<num_words; ++iter)
printf("%s %d\n",table[iter].word,table[iter].count);printf("%s %d\n",table[iter].word,table[iter].count);
return EXIT_SUCCESS; return EXIT_SUCCESS;
}}
3636Stroustrup/ProgrammingStroustrup/Programming
Word counting example Word counting example (most of main)(most of main)
record table[MAX_WORDS + 1];record table[MAX_WORDS + 1];
int num_words = 0;int num_words = 0;
char word[MAX_WORD_LENGTH + 1];char word[MAX_WORD_LENGTH + 1];
int iter;int iter;
while(scanf("%" XSTR(MAX_WORD_LENGTH) "s", word) != EOF) {while(scanf("%" XSTR(MAX_WORD_LENGTH) "s", word) != EOF) {
for(iter = 0; iter < num_words && strcmp(table[iter].word, word); ++iter);for(iter = 0; iter < num_words && strcmp(table[iter].word, word); ++iter);
if(iter == num_words) {if(iter == num_words) {
strncpy(table[num_words].word, word, MAX_WORD_LENGTH + 1);strncpy(table[num_words].word, word, MAX_WORD_LENGTH + 1);
table[num_words++].count = 1;table[num_words++].count = 1;
}}
else table[iter].count++;else table[iter].count++;
if(num_words > MAX_WORDS){if(num_words > MAX_WORDS){
printf("table is full\n");printf("table is full\n");
return EXIT_FAILURE;return EXIT_FAILURE;
}}
}}3737Stroustrup/ProgrammingStroustrup/Programming
Word counting example Word counting example (C version)(C version)
CommentsComments In (some) colloquial C style (not written by BS)In (some) colloquial C style (not written by BS) It’s so long and complicated! (my first reaction – BS)It’s so long and complicated! (my first reaction – BS) See, you don’t need any fancy and complicated language features!!! (not See, you don’t need any fancy and complicated language features!!! (not
my comment – BS)my comment – BS) IMHO not a very good problem for using CIMHO not a very good problem for using C
Not an atypical application, but not low-level systems programmingNot an atypical application, but not low-level systems programming It’s also C++ except that in C++, the argument to It’s also C++ except that in C++, the argument to qsort() qsort() should be cast to should be cast to
its proper type:its proper type: (int (*)(const void*, const void*))strcmp(int (*)(const void*, const void*))strcmp
What are those macros doing? What are those macros doing? Maxes out at Maxes out at MAX_WORDMAX_WORD words words Doesn’t handle words longer than Doesn’t handle words longer than MAX_WORD_LENGTHMAX_WORD_LENGTH First reads and then sortsFirst reads and then sorts
Inherently slower than the colloquial C++ version (which uses a Inherently slower than the colloquial C++ version (which uses a mapmap))
Stroustrup/ProgrammingStroustrup/Programming 3838
More informationMore information
Kernighan & Ritchie: The C Programming LanguageKernighan & Ritchie: The C Programming Language The classicThe classic
Stroustrup: TC++PL, Appendix B: CompatibilityStroustrup: TC++PL, Appendix B: Compatibility C/C++ incompatibilities, on my home pagesC/C++ incompatibilities, on my home pages
Stroustrup: Learning Standard C++ as a New Language.Stroustrup: Learning Standard C++ as a New Language. Style and technique comparisonsStyle and technique comparisons www.research.att.com/~bs/new_learning.pdfwww.research.att.com/~bs/new_learning.pdf
Lots of book reviews: www.accu.orgLots of book reviews: www.accu.org
3939Stroustrup/ProgrammingStroustrup/Programming