Advanced C TIPS and TECHNIQUES

 C TIPS and TECHNIQUES


Data Presentation


  • How will you represent -ve and +ve numbers in binary format ? Can you represent 0-127 +ve numbers and -1 to -128 -ve numbers ?

01111111 this is 127 the MSB is 0 in +ve series

……

……..

0000001  this is  1 

0000000  this is  0

11111111  this is -1  the MSB is 1 in -ve series

….

…...

1000000  this is -128

Using 2’s complement notation we can positive or negative values to each bit pattern.

  • What are C’s basic data types can you explain ?

C's basic data types are char, int, float, and double. Each size is machine dependent, but typical machines use 8 bits for a char, 32 bits for a float, and 64 bits for a double. The size of an int reflects the word size of the machine and is typically 16 or 32 bits.


  • What are qualifiers for basic data types ?

C provides long, short, and unsigned qualifiers for integer data types. A long is usually twice the size of an int on 16-bit machines, but long's and int's are often the same length for 32 bits and more. Going the other way, a short is half the size of an int on 32-bit machines, and short's are typically the same length on 16-bit machines. unsigned treats the most significant bit as a data bit and applies to char, int, short, and long data types. C integer data types are signed by default.


  • What are the basic data types in C and What are derived data types in C ?

    • char, int, float, double in addition there are number of qualifiers such as short (16 bits long) and long (32 bits). Int is either 16 or 32 bits depends on compiler, which is free to choose it.

    • Signed and unsigned are used prefix to char or any int.  Unsigned number are always positive or 0. Will vary from 0 to 255

    • Signed char will have values between -128 to 127 (in a 2’s complement machine), Is machine dependent .  But printable character’s are always positive.

    • Long double specifies extended precision floating point.

    • <limits.h> and <float.h> header files contains contains symbolic constants for all of these sizes , along with other properties of machine and compiler. 

    • Char constant is an integer written as one char in single quotes such as ‘x’ the value of a char constant is numeric value in the machine’s char set.  The char constant ‘\0’ represents NULL character and value is ZERO

    • A constant expression is an expression which evolves only constant.  Such expressions may be evaluated at during compile time rather than run-time

    • A string constant or string literal sequence of zero or more character’s surrounded by double quotes, as in “I am a string” or “ “

    •  There is another constant i.e. enumeration constant enum boolean {NO, YES}; it starts from 0,1 unless specific values assigned


  • Explain the data representation in C (signed data and unsigned data)

The MSB bit decides whether the data is signed or unsigned data,  The unsigned data are 2's compliment numbers.


Bit Pattern  Value

 

01111111    127

...

.....

00000001   1

00000000   0

11111111    -1

11111110   -2

...

.....

10000000 -128


Functions


  •  How will you distinguish between char constant and a string 

    • A character constant surrounded by single quotes ‘x’ and a string is “x”.  The ‘x’ is an integer and used to produce numeric value of the letter x in the machine character set.  The “x” is an array of character contains one character x and ‘\0’ 


  • What are the 2 basic function usage rules ?

    • Compiler does not convert function parameters float to int and vice versa. For example to use sqrt() in your C program you should use #include<math.h> header file. Otherwise the output will be meaning less.

    • If function returns other than int then you must specify before calling


Operators and Expressions

  • The % operators does not apply to two basic data type what are those ?

    • float, double


  • What are different operators in C

    Arithmetic, Relational, Logical, Bitwise, Assignment, Conditional, Increment and Decrement operators


Control Flow Constructs

  • What are different kinds of control flow constructs in C

    • if, if-else, while, do-while, for, switch, break, continue, goto

  • What is a NULL statement how it is terminated ?

In C the statements terminated with semicolon. C allows null statements (i.e. a semicolon with nothing else);


Array and Pointers
  • What is an array ? What are single dimension and multidimensional arrays ? Can you explain me how the following will be stored and what will be its size?

char gree[] = "hello"

sizeof(gree) ----> is 6 because 5 char + 1 NULL string appended by Compiler


  • What is a pointer ? What is indirection operator ? What is size of a pointer ? Can you explain with an example pointer to a pointer ?

int i = 3;

int *p = &i;

int **q = &p;


  • Can you explain command line arguments with an example ?


    Structures and Unions

  • What is the difference between a Structure and a Union ?

    Union allocated the biggest variable and Structure allocated memory each member.


  • What are the different types of operators C provides to access a structure ?

    dot and arrow


    Storage Classes

  • What are different types of storage classes ?

Automatic, Static (Internal static - is a local to file, External Static - Global), Register, Extern

Before program uses auto variable value it should have an initial value.

Static variable has a value ZERO before a program starts running, stored in initialized BSS (Data segment)


A variable is a Internal static when you declare it inside a block with a keyword static. Note that static storage class does not affect the variable scope.


Address operator (&) cannot be applied to a Register variable. Use of register variable is highly machine and compiler dependent. Register variable are handy for time critical code.

  • Initializing a static variable is a one step process compared to automation variable is a 2 step process.  Can you explain with an example ?

    • For example: 

{

int var1 = 3;        /* automatic variable */

static int var2 = 4; /* internal static variable */

var1 compiler allocates storage on the stack and compiler generates assembly code to load a constant 3 in that location.

var2 lives in initialized data .  The initialization is systems job not compiler.  The value 4 loaded into memory before your program runs.  Hence Initializing static variable is a one step process.

  • Difference between initializing char array and pointer

char buf[] = “hello.”

Char *p = “goodbye”


buf most likely declared outside the function

buf is the address of the char array 6+1 ie. ‘\0’ at the end

buf is a array name which is constant this is important because you can’t re-assign a new string

I.e. buf = “new string” /* illegal, does not compile */  

Because it is something like you are trying 5=6;

buf is a address of a first array element 


p is a pointer to a char string

if you change the value of p, you change what it points to

I.e p = “new string” 


  • What will happen when you make a function as static ? 

    If you make a function as static in kernel driver,  the function names will not be exported to kernel symbol table. 

  • When the compiler runs out of physical CPU registers, what will happen to the variables that you declare as register ?

It becomes Automatic


  • What are the advantage/disadvantage of Register variable

    Disadvantages:

    You can't apply & (address) operator on register variables

    Highly machine and compiler dependent 

    Very limited resources of the variables. When resources are not available the register declared variable will become automatic


    Advantages:

    Executes faster 

    Best suited for time critical functions


Preprocessor Directives and Macros

  • Explain the difference between Preprocessor directives and Macros ?

Adv - macros executes faster, but Disadv - Increases code size

  • What is casts why it is used ?

Cast is an operator, It converts the result is evaluated expression to the specified data type at run time. The values of the variables inside the expression are unaffected.

(type) expression;


  • What are the 4 program areas of run-time environment ? (Text, stack, data and heap area's)

  • What is stack frame ? 

    • When a system calls a function, the system pushes functions argument, local variables and return address on stack. We call this information as stack frame

  • Can you explain How the function pointers are stored ? How is stack frame construction when variable address is passed to function ?

  • Do you know by using which pointer information from stack frame the compiler generates the assembly code ?

    • Compiler generates assembly code using base pointer of the current stack frame to reference function arguments with a positive offset and automatic variables with a negative offset

  • What are different ways to call a function ? Can you explain difference between call by address and call by value ?

    • The call by value function uses the copies stored in the current stack frame and has  no way to refer or alter a and b.  This is the main difference between passing the address of a variable and passing its value.

  • How C reduces the runtime overhead in case of automatic variables ?

  • What is a volatile variable, explain its effect w.r.t compiler, w.r.t caches.

  • What are atomic operations ? Do you need hardware support for atomic operations ? 

  • What is recursive function ? What happens recursive function called unconditionally ?

    • A function called itself more than one time called recursive.  The You may run out of stack space


  • Can you explain non local control transfer ?

    • The C limits the destination of a goto to within the same function. The C library functions setjmp() and longjmp() provide capability to transfer control to another function.


  • Explain how does setjmp() and longjmp() works ?  or what is context switch explain it ?

    • setjmp() save the program environment ? is a machine dependent part because routine has to access all the machine registers and save them in jmp_buf array.  First time the setjmp() called the routine returns 0. As you will see it is not necessary for setjmp() to save stack frames or anything else.

    • longjmp() restore the program environment ? restores original machine registers saved by setjmp() and force machine to execute a different set of instructions.  Instead of executing next line in your program now returns from setjmp() with a non 0 value.   This changes a program to execute path, and we call it as a context switch.  Note that longjmp() function declared as void and you never return from a longjmp() call. 



C Debugging Techniques 

  • Overview of C debugging
    • C Preprocessors
    • ASCII and Hex debug display
    • Signals with debug output
    • Assertions
    • Selective Debug prints
    • Customised memory allocators

The Standard C compiler Under UNIX


Command cc file naming conventions


pgm.c - Source file

ppm.o - Object file (unlined)

ppm.s Assembly language source file

lib.a Archive (library) file 


Commandline options affecting the cc


Compiler Options

-O Optimize the step

$ cc -O prog.c sup1.c quick.s dbug.o 

compile and optimise prog.c and sup1.c, assembles quick.s and links to dbug.o This is completely depend on compiler. 


-c Suppress link edit step

$ cc -c objalloc.c debug.c 

the command creates two object files objalloc.o and debug.o with the "-c" option then neither of them are executable.

$ cc objalloc.c debug.c  

which creates a.out 


-S Assembly language listings

$ cc -S -O idim2.c 

This option creates assembly language program.  This option suppress the link edit step

 

Link Editor Options

-o Rename Object/Executable file

$ cc prog.c objalloc.c debug.o -o prog 

This create an executable file with the name prog

 

-l Name Libraries

$ cc servo.c-o servo -lm  

-lm makes the link editor to search the library


-i sharing text space

$ cc -i database.c -o database

database a pure object code file That is, the loader places the text and data segments in separate areas of memory.  e.g. /bin/sh and the editor /bin/vi are compiled with -i option. These programs have a read-only text space that user programs share from the same in-memory copy.  Each user with its own data area, but not it's own text area.


-s Strip an Executable Object file

Once the program is debugged you may want to reduce the size of its executable object file.  The -s option makes the link editor "strip" the relocation and symbolic information from an object file.


Preprocessor Options

-E Debugging the Preprocessor

$ cc -E setbit2.c

Makes preprocessor display on standard output what it's doing.  The most useful option to debug preprocessors.


-P Preprocessor File Output

$ cc -P mdim2.c

makes the preprocessor dump its output to a file


-D Preprocessor Defines

In the below example,

#ifdef DRIVER

main(){

....

}

#endif


The -D option compiles the driver


$ cc -DDRIVER dbug.c -o dbug


You can also use the -D to set constants


#define VERSION 5.0


In command line 

$ cc -c dbug.c -DVERSION 5.0 


-I Preprocessor include files

$ cc -c -O -I /usr/atl/include objalloc.c dbug.c

The -I option makes preprocessor to search the include files in a directory other than /usr/include 


#include "obj.h"

#include "dbug.h"


If the files are not available in the current directory then they sear under /usr/include

Another use is to substitute your own macros and header files for the ones in /usr/include


Compiler Debugging Options

-g Symbolic Debugging

$ cc -g -c objalloc.c dbug.c

$ cc -g -DDRIVER strmob.c objalloc.o dbug.o -o strmob


The UNIX and V provides symbolic debugger called sdb and the BSD provides symbolic debugger called dbx 


-p Performance Ananlysis

$ cc -p -c objalloc.c dbug.c

$ cc -p -DDRIVER strmob.c objalloc.o dbug.o -o strmob

$ prof -g strmob


UNIX System V also provides a tool called prof to study where a C program is spending its time and how many times your program calls each routine.  This routine will tells you which routine you need to improve the performance of a program.

  • First you need to compile program with -p option
  • Second you need to run your program which writes the profiling information to a file mon.out
  • Then you need to run prof tool to gather profiling information and display it for you.


The Run Time Environment

C is special in that you tell compiler where to place a variable in runtime environment.  The compiler does't decide, you do. It gives more control of executing your program.  The programmer must have a clear idea about what he/she is going to do. This is why it makes sense to find out how the C programs executes.  Understanding the runtime environment helps you to diagnose runtime bugs and write faster code.


Program Areas

  • The four program areas of the runtime environment; the
    • text area
    • stack
    • the data area
    • heap area
  • The text and data area are fixed.  Stack and Heap area's are dynamic means a program uses this area as it grows. The stack and heap are opposite end of memory.
Program areas at run time



Text Area
  • Reserved for executable instructions of a program
  • Is a readonly memory area by the system and often called program text
  • C compilers typically have compiler options to place text and data in separate spaces; this is sometime called pure It's possibly impure programs to modify themselves
  • The size of text area is fixed, determined at the time the program is compiled and linked.
  • The only time a program should access data in this area is with pointers to functions.
Data Area
  • It is also called static data
  • Static variables internal and external as well as global variables from your program
  • Decided into two parts; initialised and uninitialized
  • The system store variable depends on how you declare it,
    • If static or global variables initialized - goes into initiated area
    • Otherwise goes into uninitialised area
  • Uninitiazed data area sometime called as BSS (Block Started by Symbol)
  • The system fills the BSS area with ZEROs
  • We refer to variables in data area as load-time variables because the size is determined during loadtime
  • The loadtime variables have predetermined values when your program begins running.  Because the system allocates memory for loadtime variables and initialised with predetermined values and fills BSS area with zeros
The Stack
  • The stack is basis for what's called stack frame which is a mechanism that many compilers use to implement the function calls.
  • When you pass a parameter to function, the stack frame makes the data accessible to the function.
  • Compiler stores the Automatic variables in stack area
  • Since it happens in runtime,  the system can't determine the size of the stack before it runs.
  • Size of the stack changes as the program runs
  • The stack constantly growing and shrinking during the life of a program
The Heap
  • A heap manager, separate from your program, provides C library functions that allocate and deallocate storage. 
  • Pointers allow you to access heap memory as if it were an array, a structure or any C datatype
  • Heap is under programmers control and dynamic 
  • It's possible to use all heap space when a program runs
  • Programmers responsibility to address heap data properly and detect heap overflow errors

The TEXT area

Pointers to Functions

  • C program does not usually access the text area unless you use pointers to functions
  • Let's review pointer to function
int (*p) ();
  • The paranthesis surrounding the pointer *p is an indirection operatior.
  • Once you have declared you must initialise it
int func();
  • informs compiler that func is a function that returns integer
  • It's not necessary to pass function parameters here, compiler just want to know function name and return type
p = func;

  • Note that p must be a same datatype that func() returns; otherwise cast is necessary
  • parentheses does not necessary after function name; if you use them compiler tried to call that function
  • The second way to declare and initialising in the same statement
int func(), (*p)()=func;
  • Regardless of how you do, the pointer contains an address from the text area 

The Stack

  • What is a Stack ?
    • Simple data structure that stores the value, is a best example for last-in/first-out and also linked list (because the base pointer of the current stack frame contains the address of next stack frame pointer)
    • Stack used to store address or data
    • The system typically pushes and pops items on and off the stack in a last-in/first-out mannet
  • What does C store on stack ?
    • Automatic variables
    • Function parameters
    • Return address of functions
    • Temporary variables during expression evaluations
  • What is stack frame ?
    • When your program calls a function, system pushes important information like functions argument, local variables, and return address on stack.  We call it as stack frame
    • A separate stack frame each time system calls a function.
    • Not all C compilers use stack frames, some of them use registers which is faster than accessing the stack memory.
    • The compiler generates assembly code using base pointer of the current stack frame, 
      • reference function arguments with positive offset
      • automatic variables with negative arguments
  • What is the difference between calling a function with address as parameter and pass by value as parameter ?
    • The function uses the copy of the values stored in a frame in pass by value.
    • The function uses the address of a variables in pass by address, where the changes are reflected to variables
  • How does the printf() value of val and address of buf ?
    • Since we assume function arguments are pushed in reverse order on the stack, a pointer to the format string "%d %s" appears on top.
    • printf() can use the above information to determine how many arguments were passed and whether to interpret them by address or value
  • What about stack requirements ?
    • The stack frame requires is always the size of a pointer to the specified data object.
    • Passing address of an object, therefore, saves stack space and minimises the execution to setup a stack frame
  • What happens when we pass a structure ?
    • system duplicate the entire structure, resulting in a larger stack frame
    • compiler generates assembly code to copy all of the data to the new stack frame as well.

Initialising Automatic Variables

  • Why automatic variables are not initialised ?
    • When you initialise automatic variable, compiler generates additional assembly code to load the variable with a value.
    • Another reason is C allows goto's to jump into the middle of the block inside the same function. If a variable declared inside that block what is it's value ? compiler initialised automatic variable , it would have taken into special case into account.
For all these reasons C does not initialise automatic variables by default.  Their values are simply what's on the stack at runtime.  This illustrate the C's basic philosophies  -  reducing runtime overhead.
Recursive functions and Stack Overflow: When a recursive functions called too often you may run out of stack space (a condition called stack overflow) 



Nonlocal Control Transfers


What happens when you need to transfer program control to different functions ?

  • C library provides setjmp() and longjmp() provide this capability
  • The header file setjmp.h defines jmp_buf
  • Programs must use setjmp() and longjmp() in pairs
  • setjmp() routière called to save the program environment
  • The setjmp() returns 0 when you call it first time, otherwise it returns value of longjmp() second argument called somewhere else in your program
  • That's why you need to check the setjmp() return value after you call it
How does setjmp() save the program environment ?
  • Machine dependent because it has to call machine registers and save them in jmp_buf array
  • It's not necessary to save stack frame or anything else
How does longjmp() restore program environment ?
  • Calling logngjmp() restore all the original machine registers saved by setjmp()  to force the machine to execute a different set of instructions 
  • The program now returns from setjmp() with a nonzero value, This changes the execution path , and we call it as context switch
  • Note that longjmp() is declared void and never return from longjmp() call

The Data Area

  • Holds the program's data
  • Whatever the variable or data that you place here exist for the life of your program
  • The data area has two sections
    • One of them set aside for variables that you initialise
    • Other on't you don't
  • Allocation
    • Internal and External static variables
    • Global variables
    • Initialised arrays and structures
    • Constant strings
  • Internal static means a static variable declared inside a function or block
  • A variable private to it's file where it is declared called External Static
  • Global variables can be accessed out side of the file 
  • Constant strings are compiler dependent, most of the C compilers place them in data area.
  • Some C compilers give you an option for placing constant strings in text or data area.
BSS (Block Started by Symbol)


The data area decided into two separate sections, Static variables may appear in either one.  

  • Static variable without initialisation, it goes into a special part of the data area called the BSS
  • Otherwise it is placed into other section, initiazed data
  • Separating initiazed, uninitialised done by loader
  • C guantees un-initiazed static and global variables have zero values before a program runs
  • variables scope nothing todo with BSS
  • Compiler marks these variables so that loader group them together at link time
  • When it's time to run the program, the system load BSS variables into section of memory and zero-fill it all at once.  It is faster than initialising a variable at a time.
  • constant strings never be placed in BSS because they must be initialised
Initiazation
  • contains static and global variables that you explicitly initiaze in a C program
  • system initialise each variable in memory before program runs
  • constant strings, if they are stored in the data area, appear in initialised data.
Why it is important ? Why no-runtime overhead for initialising static and global variables ?

Consider an example,

{
int var1 = 3;                  /* automatic */
static int var2 = 4;        /* internal static */
..
....
}  


  • var1 is automatic compiler allocates storage on the stack. Following this, compiler generates assembly code to load a constant 3 in that location.  This is a two step process.
  • var2 lives in initialised data, 
    • Initialisation is systems job not compiler
    • the value 4 loaded into memory for var2 before program runs
    • there-fore initialising static variable is a one-step process
  • no-runtime overhead for initialising static and global variables.  Because compiler does not produce assembly code for initiazation
What about static declaration inside loop ?

  • retains it's previous value each time through the loop

/* loop2.c - creates static variable */

#include <stdio.h>

main ()

{

   int i;

   for (i 0; i < 3; i++) (

           static int j 10;

           printf("i %d\tj %d\n", i , j);

           j++;

}

$ loop2

i = 0 j =10

i = 1 j = 11

i = 2 j = 12


Constant Strings

  • C provides character constant and constant strings
  • When you enclose ASCII character in single quotes conpiler uses constant and not a memory location. e.g. compiler generate 6b for 'k' 
  • Constant strings allocated one byte for each character and one additional byte at the end i.e. NULL character
  • C allows constant strings for the following items
    • Initialising character pointer - char *boy = "kellen";
    • Assignment statement of character pointer - boy = "kellen";
    • Functions with character pointer - puts("kellen");
    • Character pointer references
Initize the character array

char girl [] = "sara";
or
char girl[] = {'s', 'a', 'r', 'a', '\0'};

will not be treated as a constant string.

/* strcon.c - constant strings as arrays and pointers */

main()

{

      printf("%s\n", "hello again" 6);

      printf("%c\n", *("12345" 3));

      printf("%c\n", "12345"[1]);

}

strcon

again

4

2


There are few more interesting problems


/* dup2.c - duplicate strings */

main()

{

   char *p, *q;

   p = "string";

   q = "string";

   p[3] '0';

   printf("%s %s\n", p, q);

}

$ dup2

strong string


The Heap

  • Allows programmers to allocate memory dynamically
  • It's possibly however heap and stack share the same memory segment
  • Stack growing down and Heap growing up in memory
  • It is required to monitor both these Heap and Stack area's  
  • Heap is controlled by Heap manager, which allocate and deallocate memory
  • User programs interface heap via C library calls
  • Following functions are available

TABLE 2-1. C library calls for the heap


Routine                                                             Meaning


char *malloc(size)                                             Allocate storage

unsigned size;                                                   for size bytes


char *calloc(n, size)                                          allocate and zero storage                

unsigned n, size;                                               for n items of size bytes


char *realloc(pheap, newsize)                          reallocate storage

char *pheap;                                                     for old heap pointer pheap

unsigned newsize;                                            for newsize bytes


void free(pheap)                                                free storage

char *pheap;                                                     for heap pointer pheap


  • malloc() returns heap address, on failure returns NULL
  • calloc() fills up heap memory with zeros there fore runs slower than malloc()
  • calloc() returns heap address, on failure NULL
  • realloc() allows you to change the size of any object on the heap, can increase/decrease objects size in heap memory 
  • Occasionally, realloc() returns same heap address
  • free() doesn't return anything 
Initialising Program Variables


  • Illegal initialisation


main ()

{

    char buf[S];                    /* stack */

    static char *p = buf;       /* initialized data */

}


  • This one correctly initializes a pointer variable at load time.


main ()

{

    static char buf[5];       /* BSS - buf initialized with zero */

    static char *p buf;   /* initialized data area */

}

  • Automatic variables on stack area

main()

{

    char buf[5];      /* stack, buf is stored with junk values */

    char *p buf;  /* stack */

}

  • Static buf and automatic pointer 

main()

{

    static char buf[S];   /* BSS - buf initialised with zero */

    char *p buf;       /* stack */

}


Use with Functions


  • you want to declare a variable and initialize it with a function call. With automatic variables, this is legal.

int length = strlen(argv[1]);

  • You can't initialise a static variable to the value of another static variable, We can't use functions return value either.  Because both actions are RUN time events 
static int length = strlen(argv[1]);  /* Does't compile */
  • You can split above statement into two, which works

static int length;                 /* BSS */

length = strlen(argv[1]);



What about pointers to functions ?

  • You can initialise both automatic and static pointers to functions, because function address are known at load time
main () {

int f();

int (*p) () = f;                /* auto, stack area */

static int (*q) () = f;      /* initiazed data area */
...
......
}
f() {                          /* text */
...
.....
}

  • Do not return the address of an automatic variable from a function (refer page 104 for example)

Summary

  • C programs use the text, stack, data, and heap program areas of the run time environment. It's possible that a program will not use the data or heap areas.
  • The text area is normally write-protected from an executing program. Pointers to functions are addresses from the text area.
  • The compiler uses the stack for function return addresses, stack frames, and intermediate storage.
  • The compiler also uses the stack for automatic variables and recursive functions.
  • The data area contains program variables that store values for the life of your program.
  • The BSS part of the data area contains the uninitialized static and global variables from a C program.
  • All static and global variables in the BSS have zero values before your program runs.
  • Constant strings typically live in the data area, but some compilers may place them in the text area.
  • The compiler usually makes separate copies of a single constant string in the data area if you define it more than once. The implementation of constant strings is compiler and machine dependent.
  • The heap is memory you control from C library routines. Heap memory is preserved through function calls.
  • The heap and stack sometimes share the same memory area; hence, a large amount of heap space may decrease the amount of available stack space, and vice versa.
  • The text area and data areas are fixed in size when your program runs. The stack and heap are dynamic.


An Array of Choices

  • The compiler treats array names as constants
  • The array names is a pointer
  • a[i] = (*(a+i)) = (*(i+a)) = i[a]
  • C allows two arithmetic operators (+ and -) with operator and an integer expression
  • Compact pointer expressions: We call pointer expressions that uses indirection (*) and auto increments (++) or auto decrements (--) compact pointer expressions.  In the most cases compiler produces assembly code that is smaller size and runs faster.
Expression    Operation           Effects
--------------------------------------------------
*p++              post increment   pointer
*p--                post decrement  pointer
*++p              pre increment     pointer
*--p                pre decrement    pointer

++*p              pre increment      object
--*p                pre decrement     object
(*p)++           post decrement    object
(*p)--             post decrement    object
----------------------------------------------------
  • You can't use pointer to a structure, union or function with these expressions  
  • Negative subscripts:
&a[n] = a+n = (char *)a + n + sizeof(object)
Now, substituting 0  for n we have
&a[0] = a = (char *)a

  • This explains why array subscripts starts at ZERO. 
  • The compiler always use the base address for the start of the array
  • What happens when n is negative ?
&a[-n] = a-n = (char *)a -n * sizeof(object)

The pointer offset if below the base address of the array.  This shows negative subscripts are legal in C.


Programming questions

  • Program to find a number palindrome or not
  • A program logic to take 100 digit number as input and increment it by 1
  • Write a program to convert integer number to hex
  • Write a program to set, unset the nth bit 
  • Write a program to count number of char in a string
  • W.A.P to find size of integer without using sizeof
  • write a macro to find MIN of two variables, three variables.
  • W A P to find all combinations of lucky number for your vehicle registration.
  • Lucky number is formed using one’s b’day. for eg: if the b’day is 15th apr 1944 

1 + 5 + 0 + 3 + 1 + 9 + 4 + 4  = 27

2 + 7 = 9

Lucky number is 9.

Now out of pattern 

KA-01, MF - XXXX 


where XXXX is the combination of numbers which make up to 9 for eg:

8001 => 8 + 0 + 0 + 1 = 9 

0711 => 0 + 7 + 1 + 1 = 9



---------------------------------------------- END -----------------------------------------------------------------------








Comments

Popular posts from this blog

Apache Ambari on ARM64

Benchmarking BigData

mockbuild warning in CentOS