Last modified: 2023-04-08

C

Wikipedia article

YearInformal nameC Standard
1972Birth
1978K&R C
1989ANSI C
1990C90ISO/IEC 9899:1990
1999C99ISO/IEC 9899:1999
2011C11, C1xISO/IEC 9899:2011
2018C17ISO/IEC 9899:2018
  • C89 / ANSI is the most important standard, a must to know in C world
    • C89 and C90 are practically identical
  • C99 and C11 are nice to have
  • It is recommended to use gcc program.c -Wall -Wextra -pedantic -std=c89 to give you additional feedback and code checks
  • Many things from C++ were backported into C99
    • like const, so you can avoid preprocessor's #define
    • and stdint.h
  • specifications of C standards (source; they are technically drafts, but are valid)

Stuff to cover

  • *.c and *.cpp contain the implementation
  • *.h contain the definitions or prototypes
  • Preprocessor
  • Header files
  • Macros
  • construction enclosed in ( and )
  • C language is stream oriented
  • Memory Layout of C Programs

Operators

Sources:

See also:

int larger;
if (a > b)
	larger = a;
else
	larger = b;
int larger;
larger = (a > b) ? a : b;

Comparison operators / relational operators

SyntaxOperator
a == bEqual to
a != bNot equal to
a > bGreater than
a < bLess than
a >= bGreater than or equal to
a <= bLess than or equal to

C++ also has this:

SyntaxOperator
a <=> bThree-way comparison

Logic operators

OperatorFunction
a && bAND
a || bOR
!aNOT
  • Non-zero values are TRUE
  • Zero is always FALSE just like \0

Bitwise logic operators

OperatorFunction
a & bAND
a | bOR
~aNOT
a ^ bXOR
a >> bright shift
a << bleft shift

Assignment operators

SyntaxOperator name
a = bDirect assignment
a += bAddition assignment
a -= bSubtraction assignment
a *= bMultiplication assignment
a /= bDivision assignment
a %= bModulo assignment
a |= bBitwise OR assignment
a ^= bBitwise XOR assignment
a <<= bBitwise left shift assignment
a >>= bBitwise right shift assignment

Member and pointer operators

SyntaxOperator name
a[b]Subscript
*aIndirection (object pointed to by a)
&aAddress-of (address of a)
a->bStructure dereference (member b of object pointed to by a)
a.bStructure reference (member b of object a)

Other operators

SyntaxOperator name
a(b, c)Function call
a, bComma
a ? b : cTernary conditional
sizeof asizeof
sizeof(type)sizeof
(type) aconversion / cast

Variables

extern

static

Sources:

static:

  • A static variable inside a function keeps its value between invocations.
    • When you use static int x = 0;, the variable is initialized to 0 only on creation and is not reset in later iterations.
    • Can be used instead of global variable.
  • A static global variable or a function is "seen" only in the file it's declared in.
  • Static variables are allocated memory in data segment, not stack segment (see Memory Layout of C Programs)
  • Static variables should not be declared inside structure. The reason is C compiler requires the entire structure elements to be placed together (i.e.) memory allocation for structure members should be contiguous.

Warning

Static variables are not thread-safe!

Note

In C++ the static can be used to define class attributes and methods shared between all objects of given class.


Arrays

Size of array

Sources:

sizeof with first element

int a[20];
size_t length = sizeof(a) / sizeof(a[0]);

sizeof with type

int a[20];
size_t length = sizeof(a) / sizeof(int);

Macro

#define NUM(a) (sizeof(a) / sizeof(*a))
for (i = 0; i < NUM(a); i++)

Compiler should be smart enough to not calculate the macro at compile time.


Libraries

math vs cmath vs math.h vs cmath.h

  • those with .h will pollute your global namespace with a lot of junk, those without may or may not (no guarantees)
  • c vs c++: prefix c is for C++ and is missing the .h at the end

stdio.h

char input[64];
fgets(input,64,stdin);

Look into format specifiers to format data.

math.h

  • usually use double
  • Order of precedence
    • equations are evaluated left to right
    • multiplication and division are done first
    • addition and subtraction
    • parentheses used to prioritize some calculations

string.h

  • C language does not have string, but rather arrays of characters
    • final character of string is null character (\0)
  • char string[] where brackets can be empty if immediate assignment, otherwise length of desired string + 1 for null character
    • char string[] = "hello";
    • char string[6]; strcpy(string,"hello");
  • string manipulation function are in string.h

stdlib.h

  • void* malloc(size_t size);
    • successful allocation returns address
    • failed allocation returns NULL pointer
      • NULL is a contant pointer, use it to check if allocation was succesful (not the same thing as \0)
char *sto;
sto = malloc( sizeof(char) * 1024 ); // want to store 1024 chars

if (sto == NULL){
	printf("Unable to allocate memory\n");
	return(1);
}

Pointers

  • pointer is declared with * operator
  • pointer type must match variable type it is pointing at
  • when used without * it represents an address
  • when used with * it represents the value at the address
int pokey = 987;
int *p = &pokey;
printf("The address of 'pokey' is %p\n", &pokey);
printf("The address in 'p' is %p\n", p);

printf("The value of `pokey` is %d\n", pokey);
printf("The value of `*p` is %d\n", *p);
The address of 'pokey' is 0x7ffd437e4a8c
The address in 'p' is 0x7ffd437e4a8c

The value of `pokey` is 987
The value of `*p` is 987

Pointer arithmetic

int array[] = {11, 13, 17, 19};
int *aptr, *aptr2;
aptr = array;
aptr2 = &array[1];

printf("Elements is %d\n", *aptr);
printf("Elements is %d\n", *aptr2);

printf("Elements is %d\n", array[3]);
printf("Elements is %d\n", *(aptr+3));
Elements is 11
Elements is 13

Elements is 19
Elements is 19

Misc

  • Required main() function (this is the entry point)
  • operator sizeof returns number of bytes used by variable
    • can be even used of struct
  • uninitialized variables contain garbage, this includes pointers
  • modulo operator % is for remainder after integer division

sizeof

struct stuff {
	int a;
	float b;
	char c[32];
}
printf("Sizeof struct is %lu bytes", sizeof(struct stuff) );

returns:

Sizeof struct is 40 bytes