Apr 04 2009
C in a Nutshell in a Nutshell
I recently finished reading C in a Nutshell, which I highly recommend as an excellent C reference and tutorial to anyone with programming experience. I previously learned some MS Visual C++ at CyberCamps some years ago, but finding the language a bit clunky, I searched around the web, found Python and have been in love with it ever since. But since every programmer should know (at least most of) C, and I had a C/Assembly course coming up, I resolved to learn C properly; hence the book. Anyway, here are my notes from it, both as a memo to myself and in the hope that others might find it mildly useful:
Interesting trivia
index[array]≡array[index]≡*(array + index)- arguments to a function may be evaluated in any order by the compiler
- The
signed-ness of plaincharis compiler-dependent
C99 Hotness
- Boolean type introduced:
#include <stdbool.h> bool a = true, b = false;
//-comments formally allowed- declarations can go anywhere within a function; C89 forces you to declare everything at the start of the function
Syntax
#include <something_in_std_lib.h>
#include "your_own_lib.h"
enum SomeEnum {A, B, C};
typedef someDeclaration newTypeAlias;
constkeyword, like Java’sfinalstatickeyword means private to this source file, like C#’sinternal
Basics
int main(int argc, char * argv[]) char aStringVariable[length];
EXIT_SUCCESS,EXIT_FAILUREdefined instdlib.h
Function pointers
int foo(char);//declare function
int (*funcPtr)(char) = foo;
int result = funcPtr('a');//use func pointer
Objects
Defining
struct Foo
//unions use same syntax, just w/ different keyword
{
int a;
char b;
}
Using
/* C99: */ struct Foo bar = {.b = 'Q', .a = 42};
/* C89: */ struct Foo baz = {42, 'Q'};
Defining macros
- Function-like macros:
#define foo(a,b) ((a)-(b)) - The
##operator within macros:- Given:
#define foo(x) MSG_##x
- Then:
foo(A)≡MSG_A
- Given:
- The
#operator within macros – converts operand to string
Useful macros
#include <assert.h> assert(booleanExpression);
#define NDEBUG– disables asserts#error "Message"– causes compile error with given message- Conditional compilation:
#if,#elif,#else,#endif
Metadata macros
__func__– name of current function__LINE__– current line number__FILE__– name of current file__TIME__– time of compilation__DATE__– date of compilation
Standards macros
__STDC__– bool for whether compiler is C89-compliant__STDC_VERSION__–199901L >=if C99-compliant__STDC_IEC_559__– bool for IEEE-754 compliance
Stdlib survey
stdlib.h:malloc(),free(), array sorting, binary search, str->num conversion, random numbersstddef.h: definesNULL,size_tstring.h: also includes general array/memory stuffmath.h,time.h: speak for themselveserrno.h: defineserrnoglobal varctype.h: ASCII character classificationfenv.h: controls floating point rounding mode, etc [C99 only]limits.h: limits of integer typesfloat.h: describes properties of float representation- See also my summary of the essential parts of the stdlib
GCC options
-o exec_name(instead ofa.out)-Idir_name:other_dir_name(places to also look for headers)-fsyntax-only(just check syntax)-ansi(use C89)-std=c99(use C99)-Wall(warn about a bunch of stuff)-pedantic(adhere pedantically to standard)-Wextra(warn about strange/pointless code)-g(add debug info)-pg(add profiling hooks)
Popularity: 1% [?]
5 responses so far
In the Quest of the Fragrant Harbour
Lacey Thoughts
League of Desmond
I realize this is in response to an old post, but “index[array] ≡ array[index]” caught my eye. That’s one of the odd trivia like interview questions I’ll ask. It makes people stop and think what an array in C really is. There’s actually another way of accessing an array element:
atl3itlt0350:~ jmcneil$ cat test.c #include int main (int *argc, char *argv[]) { int num_array[] = {1,2,3,4,5}; printf("Method One: %d\n", num_array[2]); printf("Method Two: %d\n", 2[num_array]); printf("Method Three: %d\n", *(num_array+2)); return 0; } atl3itlt0350:~ jmcneil$ make test cc test.c -o test atl3itlt0350:~ jmcneil$ ./test Method One: 3 Method Two: 3 Method Three: 3 atl3itlt0350:~ jmcneil$Yes, and in assembly language you get to know that definition quite well as you have to do the pointer arithmetic and dereferencing yourself (I recently took a class on assembly programming). I’ve now added this 3rd (and defining) array access method to the post.
Thanks for your comment; it means some people actually do read my blog :-)
Function-like macros: #define foo(a,b) a-b
Since macros are directly replaced in the code, they could be error-prone when used like functions. Therefore I strongly suggest using parenthesis in the macro definition to avoid errors due to operator precedence s.t.
#define foo(a,b) (a-b)or in the following common case:
#define sq(a) ((a)*(a))e.g. without parenthesis
foo(3,2)*5expected:
5got:
-7(3-2*5)sq(3-2)expected:
1got:
-5(3-2*3-2)Excellent point. I’ve now changed the example accordingly. Thanks!
[...] up to the second part of this blog’s tagline by being about programming! (Well, there was C in a Nutshell2, but my point is it’s been a [...]