From C++ to C

You can find notes on C++ here. This page only indicates how C differs from C++.

Parameterless functions and prototypes

In C, to indicate in a function prototype that a function does not take any parameters, show (void). For example, prototype

  void sayHello(void);
indicates that sayHello takes no parameters. You will want to use a similar heading where you define sayHello. Prototype
  void sayHello();
does not provide any information about the parameters of sayHello. It tells a C compiler not to perform type checking on parameters for this function. You almost certainly do not want that. It is present for backwards compatibility; old-style C compilers did not perform any type checking on function parameters, and some programs assumed that.

No call by reference

C does not support call by reference or reference types. Use call-by-pointer instead. That is, pass an explicit pointer. To convert from call by reference to call by pointer, do the following.

  1. In function headings or prototypes, replace & by *. That is, use explicit pointer types.

  2. In a function bodies, replace each occurrence of call-by-reference parameter p by *p.

  3. In a call to a function that formerly used call by reference, replace a reference parameter p by &p. That is, pass the address of the variable.

Not having call by reference has one advantage. You can tell by looking at a function call whether the address of a variable is being passed to a function, and so whether the function might change the variable.

Memory management

C does not support the new and delete operators. Instead, include stdlib.h and use functions malloc and free.

malloc(n)

malloc(n) allocates n consecutive bytes and returns a pointer to the first of those bytes. Its prototype is

  void* malloc(size_t n);
Type size_t is a name for unsigned int.

To get the number of bytes that an object of type T occupies, use expression sizeof(T).

Notice that malloc returns a result of type void*. You need to cast it to the type that you want. So to allocate a single Widget, write

  Widget* ptr = (Widget*) malloc(sizeof(Widget));
That is awkward. You can make it better by introducing a preprocessor definition:
  #define NEW(T) ((T*) malloc(sizeof(T)))
Be sure not to put a semicolon at the end of the #define line. It tells the preprocessor to replace NEW(T) by (T*) malloc(sizeof(T)), for any T. Using that, you can allocate one Widget as follows.
  Widget* ptr = NEW(Widget);
To allocate an array, use another preprocessor definition:
  #define NEWARRAY(T,n) ((T*) malloc(n*sizeof(T)))
Now
  char* s = NEWARRAY(char, 20);
makes s point to a newly allocated array of 20 characters.

Structure types and initialization

C does not support constructors or instance methods in structure types. To define a constructor, write it as an ordinary function. For example, you might replace C++ definition

  struct Example
  {
     int a;
     double b;

     Example(int aa, double bb)
     {
       a = aa;
       b = bb;
     }
  };
by C code
  struct Example
  {
     int a;
     double b;
  };

  Example* newExample(int aa, double bb)
  {
    Example* p = NEW(Example);
    p->a = aa;
    p->b = bb;
    return p;
  }

C++ allows constructors to be used in variable declarations, as in

  Example e(0,0);
C does not support that. C++ also allows variable declarations such as
  int n(0);
which creates n and initializes it to 0. C++ does not support that. Say
  int n = 0;

Header files

To include a standard header file in a C program, use a file name that ends of .h. Here are some C++ header files and their C equivalents.

C++ C
cstdio stdio.h
cmath math.h
cctype ctype.h
cstdlib stdlib.h

No namespaces or overloading

C++ allows overloading of function names, but C does not. Only define one function with a given name.

C++ allows names to have namespaces. C does not. Do not write

  using namespace std;
in a C program, since there is no namespace called std.

No string type

The C++ type string is not available in C. Use null-terminated strings.

No iostream library

The C++ iostream library is not available in C. Objects cout and cin do not exist in C.

No object-oriented programming

C does not support object-oriented programming. You use dot notation to indicate a particular field of a structure (or union), but you do not use dot notation to call functions. For example, s.length() not only does not get the length of a null-terminated string, it is not even sensible unless s.length is a field that is a function pointer.

No Standard Template Library

The C++ Standard Template Library is not available in C. For example, there is not type vector<int>.