• No results found

Functions/Structures and Unions

Learning Objectives

After completing this session, you will be able to:

‰ Use different storage classes in a program

‰ Use command line arguments

‰ Explain the concept of structures and unions

‰ Explain how to declare and initialise Structure

‰ Perform operations on structures

‰ Perform operation on structures and arrays

‰ Perform operation on Structures and functions

Storage Classes

Variables in C can be characterized by their data type and storage classes. Data type refers to the type of information represented by a variable and storage classes define its life time and scope.

Scope

The scope of the variable (where it can be used), is determined by where it is defined. If it is defined outside of all the blocks, it has file scope. This means, it may be accessed anywhere in the current source code file. This is normally called a global variable and is normally defined at the top of the source code. All other types of variables are local variables. If a variable is defined in a block (encapsulated with {and}), its scope begins when the variable is defined and ends when it hits the terminating. This is called block scope.

Life Time

Life time refers to the permanence of a variable – How long the variable will retain its value in memory.

General Form:

storage-class-specifier type-specifier variable-names,...

The storage-class-specifier can be any one of the following:

‰ auto

‰ static

‰ register

‰ extern

Automatic variables (Auto storage class)

Automatic variables are local (visible) to the block in which they are declared. If the variable is declared within a function, then its scope is confined to that function. Local variables of different functions/blocks may have the same name. It retains its value till the control remains in that block.

When the execution of the block is completed, it is cleared and its memory destroyed. Whenever the control again comes to the same block new memory location will be allocated to those variables. They are local or private to the function in which they are declared. Because of this property, they are also called local or internal variables. If not initialized in the declaration

statement, their initial value will be unpredictable (garbage value). If no storage class is specified, by default it is an auto variable.

Example 10.1 main()

{

int a = 5 ; {

int a =6 ;

printf (“%d “ , a); Æ prints 6 }

printf(“ %d “ , a); Æ prints 5 }

One important feature of automatic variables is that their value cannot be changed by whatever happens in some other function in the program. A variable local to the main function will be normally alive throughout the whole program, although it is active only in main(). In the case recursive functions, the nested variables are unique auto variables, a situation similar to function nested auto variables, with identical names.

Static variables (static storage class)

Static variables are also local (visible) to the block in which the variable is declared. They retain the values throughout the life of the program. Once allocated, memory will be de-allocated after the completion of the program execution. So, it will retain the value between function calls. If not initialized in the declaration, it is automatically initialized to zero. Static variables are stored in memory.

A static variable may be either internal (local) or external (global). Internal variables are those declared inside a function (or block). The scope is only to the function in which it has been declared but the variable exists in the memory throughout the entire life of the program .Thus, internal static variables retain values between function calls.

Example 10.2

Register variables (register storage class)

It is possible to inform the compiler that a variable should be kept in one of the registers, instead of keeping it in the memory. Since registers are faster than memory, keeping the frequently accessed variables like a loop control variable in a register will increase the execution speed. Since the registers are less in numbers, careful selection must be made for their use.

If the declaration of register variable exceeds the availability, they will be automatically converted into non register variables (automatic variable).

Register variables are local (Visible) to the block in which they declared. It retains its value till the control remains in that block. If not initialized in the declaration, the variable is initialized to zero.

External variables (extern storage class)

External variables are not confined to a single function. Their scope extends from the point of definition through the remainder of the program. They are referred to as global variables. Access to variables outside of their file scope can also be made by using linkage. Linkage is done by placing the keyword extern prior to a variable declaration. This allows a variable that is defined in another source code file to be accessed.

External variables can be accessed from any function and the changes done by one function will be reflected through out the entire scope. When using external variables, we must distinguish between:

‰ External Variable Definition

‰ External Variable Declaration

If not initialized in the declaration, it is initialized to zero. External variables are useful when working with multiple source files.

Example 10.3 int a = 5 ;

/* external variable definition (No need to use extern keyword) */

main() {

extern int b;

/* external variable declaration, just to say that the variable is declared somewhere else in the same program or other programs. */

void fun();

fun();

printf(“ %d “ , a); /* prints 10 */

printf(“ %d “ , b); /* prints 20 */

}

void fun() {

a = 10 ; }

int b = 20;

External variable declaration can not have initialization.

extern int a = 10; Æ invalid

Command Line Arguments

Depending on the operating system and programming environment, a C program can be executed either by selecting an icon from a graphical user interface or by entering a command in a

command window (DOS or UNIX command window). It is usually easier to write programs that are run by entering a command in a command window.

When a command is entered in a command window, it is executed by a command-line interpreter.

The operation of a command interpreter is quite complex, but as a first approximation, interpreter breaks up a command into words separated by spaces. The first word is treated as the name of a program. The interpreter searches for the program and starts it executing with the command words passed as arguments.

A C program is executed by calling its main() function. The function is called with one integer argument that indicates how many words are in the command line and another argument that is a character array of pointers containing the command line words.

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

: } Where:

‰ argc provides a count of the number of command line argument

‰ argv is an array of character pointer of undefined size that can be thought of as an array of pointer to strings, which are command line strings.

Example 10.4

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

int i;

printf(“\n Total Number of Arguments = %d”,argc);

for( i = 0; i < argc; i++)

printf(“\nArgument number %d = %s”,i , argv[i]);

}

When the following command is given in the command prompt,

C:\tc\bin> CMLPGM c cpp java (CMLPGM Æ program name, c cpp java Æ arguments)

The following result is displayed Number of Arguments = 4

Argument number 0 = CMLPGM Argument number 1 = c Argument number 2 = cpp Argument number 3 = java

Introduction to Structures and Unions

Structures and Unions are the main constructs available in C by which programmers can define new data type. Structures and unions provide a way to group together logically related data items.

Structure

Structure is a derived data type used to represent heterogeneous data items. A structure is an aggregation of components that can be treated as a single variable. The components are called Members.

For example, an employee is represented with the following attributes: employee code (string / integer), employee name (string), department code (string), salary (float).

Declaration and Initialization

Declaration

C provides facilities to define structures via a template and to declare a tag to be associated with such structures so that it is not necessary to repeat the definition. “struct” keyword is used to define structures.

General form:

struct tag_name {

type variable-name, variable-name,...;

type variable-name, variable-name,...;

type variable-name, variable-name,...;

: :

type variable-name, variable-name,...;

};

Structure-variables can be declared separately by specifying:

struct tag_name new-structure-variable;

When declaring structure variables, a separate instance of structure will be created with the name specified and memory will be allocated for that. Individual members will be given a separate memory location.

Structure definition and declaration of structure variables can be combined together. Here, tag name is optional.

Note: If tag name is not specified in the declaration, no extra structures can be created.

Example 10.5

1) struct employee

{

int code;

char name[20];

int dept_code;

float salary;

} ;

struct employee emp1, emp2;

2) struct employee (tag name is optional here) {

int code;

char name[20];

int dept_code;

float salary;

} emp1, emp2;

Initialization

Structure variables can be initialized at the time of declaration. The format used is quite similar to initializing an array. If the structure variable is declared before the main function in the global declaration section, the member variables are automatically initialized to zero or Null depending on the data type of the member variable. If it is partially initialized, uninitialized members are assigned zero or Null.

Example 10.6

struct stud {

int rollnum;

char name[20];

int semester;

float avg;

};

struct stud stud1={101,”Dina”, 1, 90.78}, stud2={102, “Raja”, 1};

For the structure variable ‘stud2’, the ‘avg’ will be initialized to 0.0

Individual structure members can be initialized only via structure variable. No storage class can be specified for structure members.

struct employee {

int empno = 101 ; Æ illegal;

static char[20] empname = “AAAA”; Æ illegal;

}

Accessing the members

Members of the structure can be accessed by using the member access operator “.”(dot). If ‘s’ is a structure variable with a member named ‘m’, then the expression “s.m” refers to the value of the member ‘m’ within the structure ‘s’.

General Form:

Two structure variables cannot be compared for equality, even though the values stored in the member variables are same. This is because, slack bytes are added in-between two member variables and these slack bytes have garbage value. While comparing structure variables, the values in slack bytes are also compared, which is always not same for different structure variables.

Assignment operation is allowed. For example, if ‘a’ and ‘b’ are two structure variables of the same structure type, the assignment expression a = b is valid. It causes each member of ‘a’ to be assigned the value of the corresponding member of ‘b’.

sizeof() operator can be used to find the size of the structure.

Example 10.8

Just as arrays of arrays, structures can contain members that themselves are structures. This can be a powerful method to create complex data types.

Note: Member structure must be defined prior to its use.

Example 10.9

struct employee

In this example, if we want to access the year of joining of an employee of emp1, then we can do so by writing:

emp1.doj.year

Structures and Arrays

A structure can be a array of structure and the members of structures can be arrays.

Example 10.10 Array of structures

struct stud

Example 10.11: Arrays within structures

struct student-mark

{

student.sub_marks[0] student.sub_mark[1]

};

Structures and Functions

Structures can be passed to a function via call by value and call by reference methods. When the structure variable (which not a pointer) is passed as an argument to a function, it is passed using call by value method. All the members are copied into corresponding formal arguments. But changes will not be reflected back.

Example 10.12

struct emp

{

int empno;

char empname[10];

};

main( )

{

void display(struct emp);

struct emp emp1 = { 101 , “AAAA”} ; display(emp1);

}

void display(struct emp emp2) {

printf(“ %d “ , emp2.empno);

printf(“ %s “ , emp2.empname);

}

Entire structure can be passed to a function using call by reference method. We can use pointer to structures, or we can pass address of the structure variable using & operator.

Example 10.13

struct emp

{

int empno;

char empname[10];

};

void main( ) {

void change(struct emp *);

struct emp emp1 = { 101 , “AAAA”} ; change(&emp1);

printf(“%d” , emp1->empno); /* prints 102 */

}

void display(struct emp *emp2) {

emp2->empno=102;

}

Function can return a structure type

struct_name = fun_name (struct_vble_name);

Function should be declared and defined as:

struct tag_name fun_name( struct tag_name struct_vble_name, …)

Example 10.14

emp1 = emp_pay (wage, x, y); Æ wage is a structure variable of sal structure.

Æ emp1 is a structure variable of employee structure.

struct employee emp_pay (struct sal pay, int a, float b) { } Æ function definition

Try It Out

Problem Statement:

Write a program to access the members of structure Code:

#include <stdio.h>

struct student {

char name[20];

float marks;

} student1, student2;

int main ( ) {

struct student student3;

strcpy(student1.name,"Tom");

student2.marks = 99.9;

printf (" Name is %s \n", student1.name);

printf (" Marks are %.2f \n", student2.marks);

getchar();

}

Refer File Name: <sesh10_1.c> to obtain soft copy of the program code How It Works:

‰ Declare student structure comprising of name and marks.

‰ In the main program assign values to both member of structure.

‰ Print the values of the structure.

Summary

‰ Structure is a derived data type used to store heterogeneous data items under a single unit.

‰ Structure members can be accessed by structure variables using dot ( . ) operator.

‰ Structures can be nested and can also have self reference.

‰ Structure can be passed to a function by both call by value approach and call by reference approach.

‰ Unions are similar to structures but the main difference is that union members share the common memory location whereas memory is allocated to individual structure members.

‰ In unions, only one member is accessible at a time.

‰ enum keyword is used to define enumerations.

‰ typedef statement is used to define new data types which are compatible with existing ones.

Test your Understanding

1. What distinguishes an array from a structure?

2. What is a self referential structure and where can it be used?

3. Consider the following structure, struct

{

int a;

int *p;

}*p1;

How can the content pointed by member pointer p be accessed via structure variable p1?

4. What will be the result when the following code is executed?

struct stud_type {

int rollno;

char name[15];

int age;

};

union person {

char surname[10];

struct stud_type s1;

}ex;

printf(“Size = %d”, sizeof (ex));

Answers:

1. The elements of an array are always of the same type, whereas the members of a structure can be of different types.

2. Self referential structures will contain a member that is a pointer to the parent structure type. It is very useful in applications that involve linked data structures.

3. *p1->p;

4. Size = 19

Session 14: Structures and Unions / Files and