Monday, January 13, 2014

Sample I2c Driver

 Sample I2c Client Driver
 
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
#include < linux/i2c.h >
#include < linux/interrupt.h >

#include

struct sample_device {
    struct i2c_client *client;
    /* TODO */
};


/* TODO */

static int __devinit sample_i2c_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
    struct sample_device *dev;
    int ret;

    if (!i2c_check_functionality(client->adapter,
        I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
        I2C_FUNC_SMBUS_I2C_BLOCK)) {
        printk(KERN_ERR "%s: needed i2c functionality is not supported\n", __func__);
        return -ENODEV;
    }
   
    dev = kzalloc(sizeof(struct sample_device), GFP_KERNEL);
    if (dev == NULL) {
        printk(KERN_ERR "%s: no memory\n", __func__);
        return -ENOMEM;
    }

    dev->client = client;
    i2c_set_clientdata(client, dev);

    // pdata = client->dev.platform_data;
   
    /* TODO: do something */

    return 0;
}

static int __devexit sample_i2c_remove(struct i2c_client *client)
{
    struct sample_client *dev = i2c_get_clientdata(client);

    /* TODO: do something */

    kfree(dev);
    return 0;
}

#ifdef CONFIG_PM
static int sample_i2c_suspend(struct i2c_client *client, pm_message_t msg)
{
    struct sample_device *dev = i2c_get_clientdata(client);
   
    return 0;
}

static int sample_i2c_resume(struct i2c_client *client)
{
    struct sample_device *dev = i2c_get_clientdata(client);

    return 0;
}

__________________________________________________________________________

Sample-I2c-Client-Board Driver

 #include
#include

/* you might add a irq or platform_data if need
 *
 * { I2C_BOARD_INFO("sample_i2c_client", 0x50),
 *   .irq = 100,
 *   .platform_data = &sample_i2c_2_pdata,
 * }
 */
static struct i2c_board_info i2c_2_sample_devs[] __initdata = {
    { I2C_BOARD_INFO("sample_i2c_client", 0x50), },

};

int machine_init(void)
{
    i2c_register_board_info(2, i2c_2_sample_devs,
            ARRAY_SIZE(i2c_2_sample_devs));

}



Linux Device and driver model

  • One of the features that came with the 2.6 kernel is a uni fide device and driver model.
  • Instead of different ad-hoc mechanisms in each subsystem, the device model uni fies  the vision of the devices, drivers, their organization and relationships.
  • Allows to minimize code duplication, provide common facilities, more coherency in the code organization.
  • De fines base structure types: struct device, struct driver
,
struct bus
type
I
Is visible in userspace through the
sysfs
lesystem,
traditionnaly mounted under
/sys

Platform device and driver

Writing Pseudo Platform device and Drivers :

#include < linux/init.h >
#include < linux/module.h >
#include < linux/kernel.h >
#include < linux/device.h >
#include < linux/platform_device.h >
#include < linux/slab.h >

struct my_platform_data {
    int a;
    int b;
};

static struct my_platform_data sample_data = {
    .a = 100,
    .b = 20,
};

static struct platform_device mydevice_device = {
    .name    = "mydevice",
    .id    = 0,
    .dev = {
        .platform_data = &sample_data,
    },
};

struct pvt_data {
    int a;
    int b;
};
static int my_device_probe(struct platform_device *pdev)
{
    struct pvt_data *pvt;
   
    pvt = kmalloc(sizeof(struct pvt_data),GFP_KERNEL);

    if(pvt == NULL) {
        printk("memory allocation failed\n");
   }
    struct my_platform_data *pdata;

    pdata = pdev->dev.platform_data;

    pvt->a = pdata->a;
    pvt->b = pdata->b;

    platform_set_drvdata(pdev, pvt);
 
    return 0;
}
static int my_device_remove(struct platform_device *dev)
{
    struct pvt_data *pvt = platform_get_drvdata(dev);
    kfree(pvt);
    return 0;
}

static struct platform_driver my_driver = {
    .driver = {
        .name = "mydevice",
        .owner = THIS_MODULE,
    },
    .probe    =    my_device_probe,
    .remove    =    my_device_remove,
};


static int __init my_device_init(void)
{
    printk("In Init\n");
    int ret;
    ret = platform_device_register(&mydevice_device);
    if(ret != 0) {
        printk("Platform device registered successfuly\n");
    }
    ret = platform_driver_register(&my_driver);
    if(ret != 0) {
        printk("platform driver registerd successfuly\n");
    }
    return 0;
}

static void mydevice_exit(void)
{
    printk("In exit\n");
    platform_device_unregister(&mydevice_device);
    platform_driver_unregister(&my_driver);
}

module_init(my_device_init);
module_exit(mydevice_exit);
MODULE_LICENSE("GPL");

________________________________________________________________________

Platform Generic driver
 
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
#include < linux/platform_device.h >

static int __devinit hello_probe(struct platform_device *pdev)
{
    printk("hello: %s entry\n", __func__);
    return 0;
}

static int __devexit hello_remove(struct platform_device *pdev)
{
    printk("hello: %s entry\n", __func__);
    return 0;
}

#ifdef CONFIG_PM
int hello_suspend(struct platform_device *pdev, pm_message_t state)
{

    return 0;
}

int hello_resume(struct platform_device *pdev, pm_message_t state)
{
    return 0;
}
#else
#define hello_suspend NULL
#define hello_resume  NULL
#endif

static struct platform_driver hello_driver = {
    .driver = {
        .name = "hello",
        .owner = THIS_MODULE,
    },
    .probe   = hello_probe,
    .remove  = __devexit_p(hello_remove),
    .suspend = hello_suspend,
    .resume  = hello_resume,
};

static struct platform_device *hello_device;

static int __init hello_init(void)
{
    int ret;

    /* register the platform device */
    hello_device = platform_device_alloc("hello", -1);
    if (NULL == hello_device) {
        printk("hello: platform device allocation failed\n");
    }

    ret = platform_device_add(hello_device);
    if (ret < 0) {
        printk("hello: unable to add platform device\n");
        goto err_platform_device_add;
    }

    ret = platform_driver_register(&hello_driver);
    if (ret < 0) {
        printk("hello: unable to register platform driver\n");
        goto err_platform_driver_register;
    }

    printk("hello: driver initalized\n");
    return 0;

err_platform_device_add:
    platform_device_put(hello_device);
err_platform_driver_register:
    platform_device_unregister(hello_device);

    return ret;
}

static void __exit hello_exit(void)
{
    platform_driver_unregister(&hello_driver);
    platform_device_unregister(hello_device);
    printk("hello: driver exited\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_DESCRIPTION("example: Hello LDM");
MODULE_LICENSE("GPL");




Sunday, January 5, 2014

Memory Layout of C Programs

A typical memory representation of C program consists of following sections.


1. Text segment
2. Initialized data segment
3. Uninitialized data segment
4. Stack
5. Heap



A typical memory layout of a running process

1. Text Segment:
A text segment , also known as a code segment or simply as text, is one of the sections of a program in an object file or in memory, which contains executable instructions.
As a memory region, a text segment may be placed below the heap or stack in order to prevent heaps and stack overflows from overwriting it.
Usually, the text segment is sharable so that only a single copy needs to be in memory for frequently executed programs, such as text editors, the C compiler, the shells, and so on. Also, the text segment is often read-only, to prevent a program from 
accidentally modifying its instructions.

2. Initialized Data Segment:
Initialized data segment, usually called simply the Data Segment. A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer.
Note that, data segment is not read-only, since the values of the variables can be altered at run time.
This segment can be further classified into initialized read-only area and initialized read-write area.
For instance the global string defined by char s[] = “hello world” in C and a C statement like int debug=1 outside the main (i.e. global) would be stored in initialized read-write area. And a global C statement like const char* string = “hello world” makes the string literal “hello world” to be stored in initialized read-only area and the character pointer variable string in initialized read-write area.
Ex: static int i = 10 will be stored in data segment and global int i = 10 will also be stored in data segment

3. Uninitialized Data Segment:
Uninitialized data segment, often called the “bss” segment, named after an ancient assembler operator that stood for “block started by symbol.” Data in this segment is initialized by the kernel to arithmetic 0 before the program starts executing
uninitialized data starts at the end of the data segment and contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code.
For instance a variable declared static int i; would be contained in the BSS segment.
For instance a global variable declared int j; would be contained in the BSS segment.

4. Stack:
The stack area traditionally adjoined the heap area and grew the opposite direction; when the stack pointer met the heap pointer, free memory was exhausted. (With modern large address spaces and virtual memory techniques they may be placed almost anywhere, but they still typically grow opposite directions.)
The stack area contains the program stack, a LIFO structure, typically located in the higher parts of memory. On the standard PC x86 computer architecture it grows toward address zero; on some other architectures it grows the opposite direction. A “stack pointer” register tracks the top of the stack; it is adjusted each time a value is “pushed” onto the stack. The set of values pushed for one function call is termed a “stack frame”; A stack frame consists at minimum of a return address.
Stack, where automatic variables are stored, along with information that is saved each time a function is called. Each time a function is called, the address of where to return to and certain information about the caller’s environment, such as some of the machine registers, are saved on the stack. The newly called function then allocates room on the stack for its automatic and temporary variables. This is how recursive functions in C can work. Each time a recursive function calls itself, a new stack frame is used, so one set of variables doesn’t interfere with the variables from another instance of the function.

5. Heap:
Heap is the segment where dynamic memory allocation usually takes place.
The heap area begins at the end of the BSS segment and grows to larger addresses from there.The Heap area is managed by malloc, realloc, and free, which may use the brk and sbrk system calls to adjust its size (note that the use of brk/sbrk and a single “heap area” is not required to fulfill the contract of malloc/realloc/free; they may also be implemented using mmap to reserve potentially non-contiguous regions of virtual memory into the process’ virtual address space). The Heap area is shared by all shared libraries and dynamically loaded modules in a process.
Examples.
The size(1) command reports the sizes (in bytes) of the text, data, and bss segments. ( for more details please refer man page of size(1) )
1. Check the following simple C program
#include
 
int main(void)
{
    return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960        248          8       1216        4c0    memory-layout
2. Let us add one global variable in program, now check the size of bss (highlighted in red color).
#include
 
int global; /* Uninitialized variable stored in bss*/
 
int main(void)
{
    return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
 960        248         12       1220        4c4    memory-layout
3. Let us add one static variable which is also stored in bss.
#include
 
int global; /* Uninitialized variable stored in bss*/
 
int main(void)
{
    static int i; /* Uninitialized static variable stored in bss */
    return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
 960        248         16       1224        4c8    memory-layout
4. Let us initialize the static variable which will then be stored in Data Segment (DS)
#include
 
int global; /* Uninitialized variable stored in bss*/
 
int main(void)
{
    static int i = 100; /* Initialized static variable stored in DS*/
    return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960         252         12       1224        4c8    memory-layout
5. Let us initialize the global variable which will then be stored in Data Segment (DS)
#include
 
int global = 10; /* initialized global variable stored in DS*/
 
int main(void)
{
    static int i = 100; /* Initialized static variable stored in DS*/
    return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960         256          8       1224        4c8    memory-layout
 
 
Source:

http://en.wikipedia.org/wiki/Data_segment
http://en.wikipedia.org/wiki/Code_segment
http://en.wikipedia.org/wiki/.bss
http://www.amazon.com/Advanced-Programming-UNIX-Environment-2nd/dp/0201433079
 

Saturday, January 4, 2014

C Interview questions and answers

Questions On Storage Class Specifier

1. What are storage class specifier?


Ans: Please refer this link : http://cinterviewquestionandanswer.blogspot.in/2014/01/storage-class-specifier.html


2. What is static variable?

 Ans :

There are 3 main uses for the static.

1. If you declare within a function: It retains the value between function calls.

2. If it is declared for a function name: By default function is extern..so it will be visible from other files if the function declaration is as static..it is invisible for the outer files.

3. Static for global variables: By default we can use the global variables from outside files If it is static global..that variable is limited to with in the file.

3. What is difference between static and extern?

Ans:
"The static storage class is used to declare an identifier that is a local variable either to a function or a file and that exists and retains its value after control passes from where it was declared. This storage class has a duration that is permanent. A variable declared of this class retains its value from one call of the function to the next. The scope is local. A variable is known only by the function it is declared within or if declared globally in a file, it is known or seen only by the functions within that file. This storage class guarantees that declaration of the variable also initializes the variable to zero or all bits off.
The extern storage class is used to declare a global variable that will be known to the functions in a file and capable of being known to all functions in a program. This storage class has a duration that is permanent. Any variable of this class retains its value until changed by another assignment. The scope is global. A variable can be known or seen by all functions within a program. ."

 4. What is difference between static local and static global variable?

Ans:
Static global  :
Static variable has scope only in the file in which it is declared. it can't be accessed in any other file but its value remains intact if code is running in some other file means lifetime is in complete program .
Static local:
static local variable has scope in that function in which it is declared means it can't be used in other functions in the same file also, means scope is limited to the function in which it is declared while its life time is also through out the program.

5. Can we declare static variable in header file?

Ans:
You can’t declare a static variable without defining it as well (this is because the storage class modifiers static and extern are mutuallyexclusive). A static variable can be defined in a header file, but this would cause each source file that included the header file to have its own private copy of the variable, which is probably not what was intended.

6. Can we declare main() function as static?

Ans:
No. The C spec actually says somewhere in it  that the main function cannot be static.
The reason for this is that static means "don't let anything outside this source file use this object". The benefit is that it protects against name collisions in C when you go to link (it would be bad bad bad if you had two globals both named "is_initialized" in different files... they'd get silently merged, unless you made them static). It also allows the compiler to perform certain optimizations that it wouldn't be able to otherwise. These two reasons are why static is a nice thing to have.
Since you can't access static functions from outside the file, how would the OS be able to access the main function to start your program? That's why main can't be static.
Some compilers treat "main" specially and might silently ignore you when you declare it static.

7. Draw memory layout of C program?

Ans : 
Refer This link:   http://cinterviewquestionandanswer.blogspot.in/2014/01/memory-layout-of-c-programs.html

8.What is volatile variable means?
volatile has nothing to deal with storage class.
volatile just tells the compiler or force the compiler to "not to do the optimization" for that variable. so compiler would not optimize the code for that variable and reading the value from the specified location, not through interal register which holds the previous value.
So, by declaring variable as volatile.. it gives garrantee that you will get the latest value, which may be alterred by an external event.
your code may be work fine if haven't declare that variable as volatile, but there may be chance of not getting correct value sometimes.. so to avoid that we should declare variable as volatile.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.

Example. reading adc values.

const voltile means you can not modify or alter the value of that variable in code. only external event can change the value.
controller pins are generally defines as volatile. may be by declaring variable as volatile controller will do "read by pin" not "read by latch"... this is my assumtion. may be wrong...
but still there is lots of confusion when to choose variable as volatile..
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
Memory-mapped peripheral registers
Global variables modified by an interrupt service routine
Global variables within a multi-threaded application

9. What does keyword const means?

Ans:
The const qualifier explicitly declares a data object as something that cannot be changed. Its value is set at initialization. You cannot use const data objects in expressions requiring a modifiable lvalue. For example, a const data object cannot appear on the lefthand side of an assignment statement
int const volatile var


10. What do the following declaration means?


const int a;
int const a;
const int *a;
int * const a;
int const * a const;

11. Can we use const keyword with volatile variable?

Ans:
Yes. The const modifier means that this code cannot change the value
of the variable, but that does not mean that the value cannot be
changed by means outside this code. For instance, in the example  the timer structure was accessed through a volatile const pointer. The function itself did not change the value of the timer, so it was declared const. However, the value was changed by hardware on the computer, so it was declared volatile. If a variable is both const and volatile, the two modifiers can appear in either order.

 Pointer String and array question :

1. What are pointers?

Ans:
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before you can use it to store any variable address. The general form of a pointer variable declaration is:
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration:
int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

2. What is dangling pointer?

Ans:
A dangling pointer points to memory that has already been freed. The storage is no longer allocated. Trying to access it might cause a Segmentation fault.
Common way to end up with a dangling pointer:
char* func()
{
   char str[10];
   strcpy(str,"Hello!");
   return(str); 
}
//returned pointer points to str which has gone out of scope. 
You are returning an address which was a local variable, which would have gone out of scope by the time control was returned to the calling function. (Undefined behaviour)
Another common dangling pointer example is an access of a memory location via pointer, after free has been explicitly called on that memory.
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!

3. What is NULL pointer?

Ans:
Null pointer is special reserved value of a pointer. A pointer of any type has such a reserved value. Formally, each specific pointer type (int*, char*) has its own dedicated null-pointer value. Conceptually, when a pointer has that null value it is not pointing anywhere.

4. What is void Pointer?
Ans:
Void pointer or generic pointer is a special type of pointer that can be pointed at objects of any data type. A void pointer is declared like a normal pointer, using the void keyword as the pointer’s type.

Pointers defined using specific data type cannot hold the address of the some other type of variable i.e., it is incorrect in C++ to assign the address of an integer variable to a pointer of type float.

Example:

float *f; //pointer of type float
int i;  //integer variable
f = &i; //compilation error

The above problem can be solved by general purpose pointer called void pointer.

Void pointer can be declared as follows:

void *v // defines a pointer of type void

The pointer defined in this manner do not have any type associated with them and can hold the address of any type of variable.

Example:

void *v;
int *i;
int ivar;
char chvar;
float fvar;
v = &ivar; // valid
v = &chvar; //valid
v = &fvar; // valid
i = &ivar; //valid
i = &chvar; //invalid
i = &fvar; //invalid  

5. What is memory leakage? How can we avoid it?
Ans :
Memory leak occurs when programmers create a memory in heap and forget to delete it.
Memory leaks are particularly serious issues for programs like daemons and servers which by definition never terminate.
/* Function with memory leak */
#include 

void f()
{
   int *ptr = (int *) malloc(sizeof(int));

   /* Do some work */

   return; /* Return without freeing ptr*/
}
To avoid memory leaks, memory allocated on heap should always be freed when no longer needed.
/* Function without memory leak */
#include ;

void f()
{
   int *ptr = (int *) malloc(sizeof(int));

   /* Do some work */

   free(ptr);
   return;
}

6. What is the size of pointer in 32 bit machine?

Ans:
Sizeof  of pointer in 32 bit machine is always 4 bytes.

7. Write a program to find weather machine is 32 bit or 64 bit?

Ans:
int main()
{
    int *p = NULL;
    if(sizeof(p) == 4)
        printf("Machine is 32 bit\n");
    else
        printf("Machine is 64 bit\n");
    return 0;
}

8. What is array?

Ans:
In C programming, one of the frequently arising problem is to handle similar types of data. For example: If the user want to store marks of 100 students. This can be done by creating 100 variable individually but, this process is rather tedious and impracticable. These type of problem can be handled in C programming using arrays.
An array is a sequence of data item of homogeneous value(same type).

9. What is difference between array and pointer?

Ans:
An array is an array and a pointer is a pointer, but in most cases array names are converted to pointers.
Here is an array:
int a[7]
a contains space for seven integers, and you can put a value in one of them with an assignment, like this:
a[3] = 9;
Here is a pointer:
int *p;
p doesn't contain any spaces for integers, but it can point to a space for an integer. We can for example set it to point to one of the places in the array a, such as the first one:
p = &a[0];
What can be confusing is that you can also write this:
p = a;
This does not copy the contents of the array a into the pointer p (whatever that would mean). Instead, the array name a is converted to a pointer to its first element. So that assignment does the same as the previous one.
Now you can use p in a similar way to an array:
p[3] = 17;
The reason that this works is that the array dereferencing operator in C, "[ ]", is defined in terms of pointers. x[y] means: start with the pointer x, step y elements forward after what the pointer points to, and then take whatever is there. Using pointer arithmetic syntax, x[y] can also be written as *(x+y).
For this to work with a normal array, such as our a, the name a in a[3] must first be converted to a pointer (to the first element in a). Then we step 3 elements forward, and take whatever is there. In other words: take the element at position 3 in the array. (Which is the fourth element in the array, since the first one is numbered 0.)
So, in summary, array names in a C program are (in most cases) converted to pointers. One exception is when we use the sizeof operator on an array. If a was converted to a pointer in this contest, sizeof(a) would give the size of a pointer and not of the actual array, which would be rather useless, so in that case a means the array itself.

10. Can we increment the base address of array? Justify your answer.

Ans: 
No, Because once we initialize the array variable, the pointer points base address only & it's fixed  and constant pointer.

11.  What is the output of program.

int a[5] = {1,2,3,4,5};

int *ptr = (int*) (&a +1);

int *ptr = (int*) (a+1); 

Ans: 
you see, for your program above, a and &a will have the same numerical value,and I believe that's where your whole confusion lies.You may wonder that if they are the same,the following should give the next address after a in both cases,going by pointer arithmetic:

(&a+1) and (a+1)

But it's not so!!Base address of an array (a here) and Address of an array are not same! a and &a might be same numerically ,but they are not the same type. a is of type int* while &a is of type int (*)[5],ie , &a is a pointer to (address of ) and array of size 5.But a as you know is the address of the first element of the array.Numerically they are the same as you can see from the illustration using ^ below.
But when you increment these two pointers/addresses, ie as (a+1) and (&a+1), the arithmetic is totally different.While in the first case it "jumps" to the address of the next element in the array, in the latter case it jumps by 5 elements as that's what the size of an array of 5 elements.
 


12. What is output of the program?

int main()
{
            int arr[10];
            int *ptr = arr;
            ptr++;
            arr++;
            return 0;
}

Ans:  
The statement arr++ will give you lvalue error. Because hear you are trying to increment base address of array and by default base address of array is constant pointer(constant value) so,
arr  =  arr+1;
i.e according to rule on LHS of assignment operator there always should be lvalue i.e variable not constant.

13. What is string?

Ans:
The string in C programming language is actually a one-dimensional array of characters which is terminated by a null character '\0'. Thus a null-terminated string contains the characters that comprise the string followed by a null.

14. What is difference between these two,


char ptr[] = "string";
char *ptr = "string";

Ans:

The two declarations are not the same.
First one is the array of character i.e. string and second one is the string literals.
char ptr[] = "string"; declares a char array of size 7 and initializes it with the characters s ,t,r,i,n,g and \0. You are allowed to modify the contents of this array.
char *ptr = "string"; declares ptr as a char pointer and initializes it with address of string literal "string" which is read-only. Modifying a string literal is an undefined behavior. What you saw(seg fault) is one manifestation of the undefined behavior.


15. Write a program to find size of variable without using sizeof operator?

Ans:

#define sizeof(var)     ( (char*)(&var+1) - (char*) (&var))

int main()
{
    int val;
    printf("size of = %d\n", SIZEOF(val));
    return 0;
}

16. Write a program to find sizeof structure without using size of operator?

Ans:

#define SIZEOF(var)     ( (char*)(&var+1) - (char*) (&var))

int main()
{
        struct s {
                int a;
                char b;
                int c;
        };
        struct s obj[1];

    printf("size of = %ld\n", SIZEOF(obj));
    return 0;
}

17. What is the output of following program?


int main()
{
      char str[] = "vishnu";
      printf("%d %d\n",sizeof(str),strlen(str));
}

Ans:
7 6
Here char str[] = " 'v'. 'i' ,'s','h','n',u','\0' ";
so sizeof operator always count null character whereas strlen skip null character.

18. Write a program to implement strlen(), strcpy(),strncpy(), strrev(),strcmp() function"?


Ans:

1. strlen:


int my_strlen(const char * str)
{
    int count;
    while(* str != '\0') {
        count++;
        str++;
    }
    return 0;
}

2. strcpy:


void my_strcpy(char * dest, const char* src)
{
    while(* src != '\0') {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
}

3. strrev:


void my_strrev(char *str,size)
{
    int i;
    char temp;
    for(i=0;i<=size/2;i++) {
        temp = str[i];
        str[i] = str[size-i];
        str[size-i] = temp;
    }
}

int main()
{
    char str[10] = "vishnu";
    int len;
    len = strlen(str);
    my_strrev(str,len-1);
    printf("strrev = %s\n",str);
    return 0;
}

4. strcmp :


void my_strcmp(char * dest, const char* src)
{
     while(*str != '\0' && *dest != '\0') {
        str++;
        dest++;
    }
    return (*src - *dest);
}

int main()
{
    char str[10];
    char dest[10];
    int i;
    i = my_strcmp(dest,src);
    if(i == 0 )
        printf("strings are equal\n");
    if(i < 0)
        printf(" string1 is less than string2\n");
    if(i > 0)
        printf("string2 is greter than string1\n");
    return 0;
} 

5. strncpy


void my_strncpy(char * dest, const char* src,int n)
{
    while(*src != '\0' && n != 0) {
        *dest = *src;
        dest++;
        src++;
        n--;
    }
    while(n) {
        *dest = '\0';
        n--;
    }
}

19 . Write a program to implement above function using recursion?


20 . Write a program to check weather  string is palindrome or not?


int main()
{
    char string[25], reverse_string[25] = {'\0'};
    int  i, length = 0, flag = 0;
    fflush(stdin);
    printf("Enter a string \n");
    gets(string);
    for (i = 0; string[i] != '\0'; i++) {
        length++;
    }
   
    for (i = length - 1; i >= 0; i--) {
        reverse_string[length - i - 1] = string[i];
    }
    if(strcmp(string,reverse_string) == 0 )
        printf("%s is palindrome\n");
    else
        printf("%s is not palindrome\n");
    return 0;
}



21 . Write a program to count total number of vowel,consonant present in given string?

Ans:

int main()
{

    char sentence[80];
    int i, vowels = 0, consonants = 0, special = 0;
    printf("Enter a sentence \n");
    gets(sentence);
         for (i = 0; sentence[i] != '\0'; i++) {

        if ((sentence[i] == 'a' || sentence[i] == 'e' || sentence[i] == 'i' || sentence[i] == 'o' || sentence[i] == 'u') || (sentence[i] == 'A' || sentence[i] == 'E' || sentence[i] == 'I' || sentence[i] == 'O' || sentence[i] == 'U')) {
        vowels = vowels + 1;
        }
        else {
            consonants = consonants + 1;
        }
        if (sentence[i] =='t' ||sentence[i] =='\0' || sentence[i] ==' ') {
            special = special + 1;
        }

    }
    consonants = consonants - special;
      printf("No. of vowels in %s = %d\n", sentence, vowels);
    printf("No. of consonants in %s = %d\n", sentence, consonants);
    return 0;

}

22. Write a function to find whether machine is little endian or big endian.?


Ans:
void is_little_or_big(int n)
    {
        int num = 0x01;
        char * ptr = (char*)num;
        if(*ptr == 1)
            printf("little endian\n");
        else
            printf("big endian\n");
    }
    or
   
    void is_little_or_big()
    {
        enum union {
            int a;
            char c[4];
        };
        enum endian obj;
        obj.i = 1;
        if(obj.c[0] == 1)
            printf("Machine is little endian\n");
        else
            printf("machine is big endian\n");
    }
 


Write a program to find occurrence of particular key in given string?


Write a program to move all 0's to one side and 1's on ther side of array?


Write a program to find largest element in an array?


Write a program to find second largest element from array?



Bit Manipulation  :

1. Write a program to count total number of setbit in 32 bit number?


int countset(int num)
{
           int count = 0;
           while (num) {
                    if( ((num) & 1) == 1)
                           count++;
                     num = num >> 1;
              }
             return count;
}
or
unsigned int countsetbit(int num)
{
           int count = 0;
           while(num != 0) {
                      count ++;
                      num = num & (num-1);
              }
             return count;
}

2. Write a program to set n th bit in 32 bit number?


int setbit(int num, int pos)
{
           num = num | 1 << pos;
}

3. Write a program to count total number of reset bit in 32 bit integer?


 int setbit(int num)
{
           int count = 0;
           while (num) {
                    if( ((num) & 1) == 0)
                           count++;
                     num = num >> 1;
              }
             return count;
}


4. Write a program to reset nth bit in 32 bit number?


int resetbit(int num, int pos)
{
           num = num &  ~(1 << pos);
}


5. Write a program to swap nibble of a 1byte data?



6. Write a program to swap two variable using bitwise operator?


void swap(int a, int b)
{
         a = a ^ b;
         b = a ^  b;
         a = a ^ b;
}

7. Write a program to find number is even or odd?


void evnodd(int num)
{
       if( (num) & (1) )
           printf("odd");
      else
           printf("even");


8. Write a program to find number is power of 2 or not?


void  power(int num)
{
       if( !( (num) & (num-1) ) )
           printf("power of 2");
      else
           printf("num is not power of 2");


9 Write a function to swap even bits with consecutive odd bits in a number.

   e.g. bo swapped with b1,b2 sawpped with b3 and so on.


 Given an unsigned integer, swap all odd bits with even bits. For example, if the given number is 23 (00010111), it should be converted to 43 (00101011). Every even position bit is swapped with adjacent bit on right side (even position bits are highlighted in binary representation of 23), and every odd position bit is swapped with adjacent on left side.
If we take a closer look at the example, we can observe that we basically need to right shift (>>) all even bits (In the above example, even bits of 23 are highlighted) by 1 so that they become odd bits (highlighted in 43), and left shift (<<) all odd bits by 1 so that they become even bits. The following solution is based on this observation. The solution assumes that input number is stored using 32 bits.
Let the input number be x
1) Get all even bits of x by doing bitwise and of x with 0xAAAAAAAA. The number 0xAAAAAAAA is a 32 bit number with all even bits set as 1 and all odd bits as 0.
2) Get all odd bits of x by doing bitwise and of x with 0x55555555. The number 0x55555555 is a 32 bit number with all odd bits set as 1 and all even bits as 0.
3) Right shift all even bits.
4) Left shift all odd bits.
5) Combine new even and odd bits and return.


// C program to swap even and odd bits of a given number
#include
unsigned int swapBits(unsigned int x)
{
    // Get all even bits of x
    unsigned int even_bits = x & 0xAAAAAAAA;
    // Get all odd bits of x
    unsigned int odd_bits  = x & 0×55555555;
    even_bits >>= 1;  // Right shift even bits
    odd_bits <<= 1;   // Left shift odd bits
    return (even_bits | odd_bits); // Combine even and odd bits
}
// Driver program to test above function
int main()
{
    unsigned int x = 23; // 00010111
    // Output is 43 (00101011)
    printf("%u ", swapBits(x));
    return 0;
}
Output:
 43 
 

10. Write a function to set a particular bit.


unsigned int setbit(unsigned inr num,int pos)
{
 num = num | (1 << pos);
 return num;
}
 

11. Write a function to clear a particular bit.

unsigned int clear(unsigned inr num,int pos)
{
 num = num & ~ (1 << pos);
 return num;
}

12. Write a function to toggle particular bit.

unsigned int togglebit(unsigned inr num,int pos)
{
 num = num ^ (1 << pos);
 return num;
}

13. Write a function to swap even bits with consecutive odd bits in a number.

e.g. b0 swapped with b1, b2 swapped with b3 and so on.

unsigned int swap_bits(unsigned int num)
{
  return (num >> 1 & 0x55555555) | (num << 1 & 0xAAAAAAAA);
}

14. Write a function to swap odd bits in a number.

e.g. b1 swapped with b3, b5 swapped with b7 and so on.

unsigned int swap_odd_bits(unsigned int num)
{

 return (num >> 2 & 0x22222222) |

         (num << 2 & 0x88888888) |

         ( num   & 0x55555555) ; 
}

15. Write a function to swap even bits in a number.

e.g. b0 swapped with b2, b4 swapped with b6 and so on.

unsigned int swap_even_bits(unsigned int num)
{
return (num >> 2 & 0x11111111) |
       (num << 2 & 0x44444444) |
       ( num   & 0xAAAAAAAA);}

16. Write a function to find out the number of 1s in a number.

unsigned int num_of_ones(unsigned int num)
{
 if( (count_ones(num) & 1) 
  return ODD;
 else
  return EVEN;
}

17. Write a function for finding the first lowest bit set in a number.

unsigned int first_lowest_bit(unsigned num)
{
 int count =0;
 while(num) {
  count ++;
  if( (num) & 1 == 1)
   break;
  num = num >> 1;
 }
 return count;
}

18. Write a function for finding the higest bit set in a number.

unsigned int first_highest_bit(unsigned num)
{
 int count =0;
 while(num) {
  count ++;
  if( (num & (1 << 31) ) == 1)
   break;
  num = num << 31;
 return count;
}

19 Write a function for reversing the bits in a number.

unsigned int reverse_bit(unsigned num)
{
 unsigned int NO_OF_BITS = sizeof(num) * 8;
 unsigned int temp,rev=0;
 for(i=0; i <= NO_OF_BITS -1 ;i++) {
  if(temp) {
   rev |= (1 << ((NO_OF_BITS-1)-i);
 }
 return rev;
}

20. Write a code to extract nth to mth bit, where n

(num >> n) & ~(~ 0 << (m-n+1))

21. write a code for toggling nth to m bits,where n < m

num ^ ((~ 0 << n) & ( ~0 >> (31-m)))


22. Write a code for setting nth to mth bit, where n < m
num | ((~0 << n) & (~0 >>(31-m)))

23. write a code for clearing nth to mth bit, where n  < m


num & ~((~0 << n) & (~0 >> (31-m))) 
 

Link List Question:

 

1. How to check whether linked list is circular or not.

Ans:
  
struct node {
    int data;
    struct node *next;
};
struct node *head = NULL;

void checkcircular(struct node *head)
{
    struct node * slow = head;
    struct node * fast = head;
    while( fast && fast->next) {
        if(slow == fast->next->next) {
            printf("Circular\n');
            break;
        }
        else {           
            slow = slow->next;
            fast = fats->next->next;
        }
    }
}


2. How would you find a loop in a singly linked list?


struct node {
    int data;
    struct node *next;
};

struct node *head = NULL:

void detectloop(struct node * head)
{
    struct node * slow = head;
    struct node * fast = head;
    while(slow && fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) {
            printf("Loop detected\n');
            break;
        }
    }
}

3. Write a C function to print the middle of a given linked list.


struct node {
    int data;
    struct node *next;
};

void findmiddle(struct node *head)
{
    struct node * slow = head;
    struct head * fast = head;
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = slow->next->next;
    }
    printf(" Middle element is %d\n", slow->data);
}


4. Write a c program to get the intersection point of two singly linked lists.


struct node {
    int data;
    struct node *next;
};

struct node * head = NULL:

int count_node(struct node * head)
{
    int count = 0;
    struct node * current = head;
    while (current != NULL) {
        count ++;
        current = current->next;
    }
    return count;
}

struct get_intersection_mod(int d,struct node * head1, struct node * head2)
{
    struct node current1 = head1;
    struct node current2 = head2;
   
    for(i=0;i        cureent1 = current->next;
    }
    while(cuttent1 != NULL && current2 != NULL) {
        if(current1 == current2) {
            printf(" intersection node =%d\n", current1->data);
            break;
        }
        current1 = current1->next;
        current2 = current2->next;
    }
}

void get_intersecton(struct node * head1, struct node * head2)
{
    struct node *current = head1;
    struct node *current = head2;
    int c1, c2;
    c1 = count_node(current1);
    c2 = count_node(current2);
    if(c1 > c2) {
        d= c1 -c2;
        get_intersection_mod(d,head1,head2);
    }
    else {
        d = c2 -c1;
        get_intersection_mod(d, head1,head2);
    }
}


Storage Class Specifier In C

1. What is storage class specifier?

Storage class specifiers in C language tells the compiler where to store a variable, how to store the variable, what is the initial value of the variable and life time of the variable. 

Syntax: storage_specifier data_type variable _name

Types of storage class specifier in c :

 There are four storage class specifier in C Language. They are,
1. Automatic
2. Register
3. Static
4. Extern

S.No.
Storage Specifier
Storage place
Initial / default value
Scope
Life
1
auto
CPU Memory
Garbage value
local
Within the function only.
2
extern
CPU memory
Zero
Global
Till the end of the main program. Variable definition might be anywhere in the C program
3
static
CPU memory
Zero
local
Retains the value of the variable between different function calls.
4
register
Register memory
Garbage value
local
Within the function

 Note:

    • For faster access of a variable, it is better to go for register specifiers rather than auto specifiers.
    • Because, register variables are stored in register memory whereas auto variables are stored in main CPU memory.
    • Only few variables can be stored in register memory. So, we can use variables as register that are used very often in a C program.

Example Program for Auto variable in C

#include
void increment(void);

int main()
{
   increment();
   increment();
   increment();
   increment();
   return 0;
}

void increment(void)
{
   auto int i = 0 ;
   printf ( "%d ", i ) ;
   i++;
}


 Output: 0 0 0


Example program for static variable in C
 
#iclude
void increment(void);

int main()
{
   increment();
   increment();
   increment();
   increment();
   return 0;
}

void increment(void)
{
   static int i = 0 ;
   printf ( "%d ", i ) ;
   i++;
}


Output: 0 1 2 3

 
Example program for extern variable in C


The scope of this extern variable is throughout the main program. It is equivalent to global variable. Definition for extern variable might be anywhere in the C program.

#inlude
int x = 10 ;
int main( )
{
   extern int y ;
   printf ( "The value of x is %d \n", x ) ;
   printf ( "The value of y is %d",y ) ;
   return 0;
}
int y = 50 ;


Output:  The value of x is 10
                 The value of y is 50



Example program for register variable in C:

  • Register variables are also local variables, but stored in register memory. Whereas, auto variables are stored in main CPU memory. 
  • Register variables will be accessed very faster than the normal variables since they are stored in register memory rather than main memory.But, only limited variables can be used as register since register size is very low. (16 bits, 32 bits or 64 bits)


#include

int main()
{
   register int i;
   int arr[5];          // declaring array
   arr[0] = 10;         // Initializing array
   arr[1] = 20;
   arr[2] = 30;
   arr[3] = 40;
   arr[4] = 50;
   for (i=0; i < 5 ; i++)  {
      // Accessing each variable
      printf("value of arr[%d] is %d \n", i, arr[i]);
   }
   return 0;
}


Output: 

value of arr[0] is 10
value of arr[1] is 20
value of arr[2] is 30
value of arr[3] is 40
value of arr[4] is 50