1. Homepage of Dr. Zoltán Porkoláb
    1. Home
    2. Archive
  2. Teaching
    1. Timetable
    2. Multiparadigm programming (MSc)
    3. C programming (BSc for physicists)
    4. Project tools (BSc)
    5. Bolyai College
    6. C++ (for foreign studenst)
    7. Software technology lab
    8. BSc and MSc thesis
  3. Research
    1. Templight
    2. CodeChecker
    3. CodeCompass
    4. Projects
    5. Publications (up to 2011)
    6. PhD students
  4. Affiliations
    1. Dept. of Programming Languages and Compilers
    2. Ericsson Hungary Ltd

The C programming language – Lecture 2.

The structure of C programs

1
2
3
4
5
6
7
8
9
10
/*
 * my first C program      // comment
 *
 */
#include <stdio.h>         // preprocessor directive
int main()
{
  printf( "hello world\n" );  // c tokens...
  return 0;   
}

C programs consist of:

Comments:

single line comment (since C99) from // to end of line

1
2
3
4
5
6
7
8
9
  /* multi
     line    
     comments
     // hiding single line comments
   */

  /*
      /*  but must not be nested */
   */

not comments inside strings: “/* this is not comment */”

1
2
3
4
5
  /*************************************\
*                                     *
*  exist in various style and format  *
*                                     *
\*************************************/

Preprocessor directives

starting with ‘#’

1
2
3
4
5
6
7
8
9
10
11
#ifdef 
#define MY_HEADER 
#include <header.h>

#if MY_PLATFORM
#define BUFFER 100
#else
#error platform not defined
#endif

#endif

… more on preprocessor in the next lecture

C tokens

keywords

all lowercase

  • C89: 32
  • C99: +5
  • C11: +7

identifyers

starts with letter (incl _underscore) continues with letters or numbers

literals

  • 1 decimal integer literal
  • 0x14 hexadecimal integer literal
  • 3.14 floating point literal
  • ‘x’ character literal
  • “Hello world” string literal

operators

  • unary e.g. -2
  • binary e.g. 2 + 4
  • terciary x<y ? x : y

separators

{ } ,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * my first C program    <--- comment 
 *
 */
#include <stdio.h>   <---- preprocessor directvive

int main()               int    <-- type name: keyword
                         main   <-- function name: identifier
                         ()     <-- function call: operator
{                        {      <-- block begin: separator
                         printf <-- function name: identifier
                         (      <-- function call: operator
  printf("Hello world"); "Hello world"  <-- string literal, type char[13]
                         )      <-- function call: operator
                         ; <-- command-end separator
                         return <-- keyword
  return 0;              0      <-- decimal int literal, type int
}                        }      <-- block end: separator

Keywords

we will learn them …

Identifiers

  • starts with letter (underscore ‘_’ is a letter)
  • continues with letters and digits
  • no maximum length
  • but compilers should translate
  • only the first 63 letters (internal linkage)
  • only the first 31 letters (external linkage)
  • must not use keywords as identifiers
  • case sensitive

Different conventions:

  • camelCaseNotation
  • CTypenamesStartsWithUppercase
  • under_score_notation

A research on this: https://whathecode.wordpress.com/2011/02/10/camelcase-vs-underscores-scientific-showdown/

results on February 2015:

  • camelCase: 52.5 %
  • underscore: 47.5 %

MACRO_NAMES_ARE_ALL_UPPERCASE by convention

A paper on this: http://www.cs.loyola.edu/~binkley/papers/icpc09-clouds.pdf

Literals

void

Integrals, type + value

  • decimal integral 12 type = int, value = 12
  • octal integral 014 type = int, value = 12
  • hexadecimal integral 0xC type = int, value = 12

  • long integer 12l type = long int, value = 12
  • long long integer (since C99)

  • unsigned integer 12u type = unsigned int, value = 12
  • signed integers are the same as integers

  • if an integer literal longer than integer 10000000 –> long or long long

  • int size knot known ==> the best for the compiler, machine word
   sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
// at least 16 bit             at least 32 bit    at least 64 bit
  • also exist signed and unsigned versions, e.g. long <==> signed long

Characters

  • character ‘A’ type = char, value = ascii value of ‘A’, likely 65
  • escape sequences:
    • ’'’ single quote
    • ’"’ double quote
    • ’\?’ question mark
    • ’\’ backslash
    • ‘\a’ bell (audio)
    • ‘\b’ backspace
    • ‘\f’ form feed – new page
    • ‘\n’ newline
    • ‘\r’ carriage return
    • ‘\t’ horizontal tab
    • ‘\v’ vertical tab
  • octal value: type = char
    • ‘\377’ -> 11111111
  • hexadecimal value type = char
    • ‘\xff’ -> 11111111
  • unicode value
    • ‘\U1234’ type = char16_t (min 16bit)
    • ‘\U12345678 type = char32_t (min 32bit)
  • wchar_t is the longest character type
  • signed char and unsigned char also exist, but here char not necessary the same as signed char
 1 == sizeof(char) < sizeof(char16_t) <= sizeof(char32_t) <= sizeof(wchar_t)

Boolean

_Bool 1 (true) or 0 (false)

bool, true, false (macro)

true –> 1 false –> 0

In conditional expressions all non-zero values are TRUE values!

Conversion of _Bool differs from int conversions:

1
2
3
4
5
6
#include <stdio.h>
int main()
{
  printf("_Bool == %d\t int == %d\n", (_Bool) 0.5, (int) 0.5);
  return 0;
}
$ ./a.out
_Bool == 1      int == 0

Floating point numbers

  • float 3.14f
  • double 3.14 (as double precision)
  • long double 3.14l
  sizeof(float) <= sizeof(double) <= sizeof(long double)

Complex floating points

                          #include <complex.h>
  float _Complex      or    float complex
  double _Complex           double complex
  long double _Complex      long double complex

Example;

1
2
3
4
5
6
7
8
#include <complex.h>
#include <stdio.h>
int main(void)
{
    double complex z = 1 + 2*I;
    z = 1/z;
    printf("1/(1.0+2.0i) = %.1f%+.1fi\n", creal(z), cimag(z));
}

Have to link to the math library! Use the “-lm” flag!

$ gcc  -ansi -pedantic -Wall -W complex.c -lm
$ ./a.out
1/(1.0+2.0i) = 0.2-0.4i

Size is not fixed! (C is NOT Java!)

int ==> best for integral computation, “machine word”

double ==> best for floating point computation