THE C PROGRAMMING LANGUAGE

[TOC]

Key Points

Forgotten Points:

Types, Values, and Variables

Types

None Type(For function parameter, function return, and pointer):

Character:

Integer:

Floating Point:

#include <stdio.h>
#include <limits.h>

int main() {
   printf("Storage size: %d \n", sizeof(double));
   return 0;
}

Values

Special literals:

Variables

When a local variable is defined, it is not initialized by the system, you must initialize it yourself. Global variables are initialized automatically by the system: int, float, double(0); char('\0'); pointer(NULL).

Constants

Storage Classes

A storage class defines the scope (visibility) and life-time of variables and/or functions within a C Program.

Special Types

Pointer

int  var = 20;  /* actual variable declaration */
int  *p_var;  /* pointer variable declaration */
p_var = &var;  /* store address of var in pointer variable*/

/* address of variable */
printf("Address of var variable: %x\n", &var  );

/* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip );

/* access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );

Size of pointer is 8:

int a = 1;
int *p = &a;
printf("Address: %x \n", p);  /* Address: e30ee768 */
printf("Storage size: %d \n", sizeof(int*));  /* Storage size: 8 */

Better to assign unused pointer to NULL:

int  *ptr = NULL;
printf("The value of ptr is : %x\n", ptr  );
/* The value of ptr is 0 */

if(ptr)     /* succeeds if p is not null */
if(!ptr)    /* succeeds if p is null */

If function returns pointer, it should be declared with static storage class.

int * getRandom( ) {
   static int  r[10];
   // ...
   return r;
}

Arrays of pointers:

int *ptr[MAX];  // An array of int pointer <=> (int*)[MAX] ptr
char *names[] = {  // <=> (char*)[MAX] ptr
    "Zara Ali",
    "Hina Ali",
    "Nuha Ali",
    "Sara Ali"
};

Strings

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char greeting[] = "Hello";
#include <string.h>

char str1[12] = "Hello";
char str2[12] = "World";
char str3[12];
strcpy(str3, str1);  // str3 <= str1
strcat( str1, str2);  // str1 <= str1 + str2
int len = strlen(str1);

Typedef

typedef struct Books {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
} Book;

Built-In Data Structures

Array

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
int a[3][4] = {  
   {0, 1, 2, 3} ,   /*  initializers for row indexed by 0 */
   {4, 5, 6, 7} ,   /*  initializers for row indexed by 1 */
   {8, 9, 10, 11}   /*  initializers for row indexed by 2 */
};
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

Struct

struct Books {
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

struct Books Book1;        /* Declare Book1 of type Book */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali"); 
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;

To access any member of a structure, we use the member access operator (.).

Structures as function arguments:

void printBook( struct Books book ) {
   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);
}

Pointers to structure:

struct Books *struct_pointer;
struct_pointer = &Book1;
struct_pointer->title;

Bit Fields

struct packed_struct {
   unsigned int f1:1;
   unsigned int f2:1;
   unsigned int f3:1;
   unsigned int f4:1;
   unsigned int type:4;
   unsigned int my_int:9;
} pack;

Note that:

Union

union Data {
   int i;
   float f;
   char str[20];
} data;
#include <stdio.h>
#include <string.h>

union Data {
   int i;
   float f;
   char str[20];
};

int main( ) {
   union Data data;        
   printf( "Memory size occupied by data : %d\n", sizeof(data));  /* Memory size occupied by data : 20 */
   return 0;
}
union Data data;        

data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");

printf( "data.i : %d\n", data.i);
printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);

/*  data.i : 1917853763
    data.f : 4122360580327794860452759994368.000000
    data.str : C Programming */

Functions

Everything is pass by value!

E.g. structs, pointers, ...

Input & Output

int getchar(void), int putchar(int c):

#include <stdio.h>

int c;

printf( "Enter a value :");
c = getchar( );

printf( "\nYou entered: ");
putchar( c );

char *gets(char *s), int puts(const char *s):

#include <stdio.h>

char str[100];

printf( "Enter a value :");
gets( str );

printf( "\nYou entered: ");
puts( str );

int scanf(const char *format, addresses...), int printf(const char *format, variables, variables):

#include <stdio.h>

char str[100];
int i;

printf( "Enter a value :");
scanf("%s %d", str, &i);

printf( "\nYou entered: %s %d ", str, i);

File IO

#include <stdio.h>

FILE *fp;

fp = fopen("/tmp/test.txt", "w+");
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);
fclose(fp);

Command-Line Arguments

#include <stdio.h>

int main( int argc, char *argv[] )  {

   if( argc == 2 ) {
      printf("The argument supplied is %s\n", argv[1]);
   }
   else if( argc > 2 ) {
      printf("Too many arguments supplied.\n");
   }
   else {
      printf("One argument expected.\n");
   }
}

Preprocessors

#include
#define
#undef
#ifdef MACRO // Returns true if this macro is defined.
#ifndef MACRO  // Returns true if this macro is not defined.
#if
#else
#elif
#endif  // Ends preprocessor conditional.
#error
#pragma

Usage:

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

#define  message_for(a, b)  \
   printf(#a " and " #b ": We love you!\n")

#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#endif

Predefined Macros:

#include <stdio.h>

printf("File: %s\n", __FILE__ );
printf("Date: %s\n", __DATE__ );
printf("Time: %s\n", __TIME__ );
printf("Line: %d\n", __LINE__ );
printf("ANSI: %d\n", __STDC__ );  // 1 when compiled with ANSI standard

Errors

#include <stdio.h>
#include <stdlib.h>

main() {

   int dividend = 20;
   int divisor = 5;
   int quotient;

   if( divisor == 0) {
      fprintf(stderr, "Division by zero! Exiting...\n");
      exit(EXIT_FAILURE);
   }

   quotient = dividend / divisor;
   fprintf(stderr, "Value of quotient : %d\n", quotient );

   exit(EXIT_SUCCESS);
}

Memory Allocation

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* allocate memory dynamically */
char *description;
description = malloc( 200 * sizeof(char) );
description = calloc(200, sizeof(char));

if( description == NULL ) {
    fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
    strcpy( description, "Zara ali a DPS student in class 10th");
}

printf("Description: %s\n", description );

/* release memory using free() function */
free(description);

Reference

by Jon