Apr 04 2009

C in a Nutshell in a Nutshell

Published by Chris Rebert at 2:12 PM

Bookmark and Share

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 plain char is 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;
  • const keyword, like Java’s final
  • static keyword means private to this source file, like C#’s internal

Basics

int main(int argc, char * argv[])
char aStringVariable[length];
  • EXIT_SUCCESS, EXIT_FAILURE defined in stdlib.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
  • The # operator within macros – converts operand to string

Useful macros

Assertions:

#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.hmalloc()free(), array sorting, binary search, str->num conversion, random numbers
  • stddef.h: defines NULL, size_t
  • string.h: also includes general array/memory stuff
  • math.h, time.h: speak for themselves
  • errno.h: defines errno global var
  • ctype.h: ASCII character classification
  • fenv.h: controls floating point rounding mode, etc [C99 only]
  • limits.h: limits of integer types
  • float.h: describes properties of float representation
  • See also my summary of the essential parts of the stdlib

GCC options

  • -o exec_name (instead of a.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

5 Responses to “C in a Nutshell in a Nutshell”

  1. Jeff McNeil says:

    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$
    
    • Chris Rebert says:

      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 :-)

  2. Emre Guney says:

    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)*5
    expected:
    5
    got:
    -7 (3-2*5)
    sq(3-2)
    expected:
    1
    got:
    -5 (3-2*3-2)

  3. [...] 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 [...]

Leave a Reply

*

 

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>