Declarations and Types
- Storage classes
- Type specifiers / Data Types
- Type qualifiers
- Declarators and variable
declarations
- Typedef declarations
1.
C Storage Classes
The "storage
class" of a variable determines whether the item has a "global"
or "local" lifetime. C calls these two lifetimes "static"
and "automatic." An item with a global lifetime exists and has a
value throughout the execution of the program. All functions have global lifetimes.
Automatic variables,
or variables with local lifetimes, are allocated new storage each time
execution control passes to the block in
which they are defined. When execution returns, the variables no longer have
meaningful values.
C provides the following
storage-class specifiers:
1.1
auto
1.2
register
1.3
static
1.4
extern
Items
declared with the auto or register specifier
have local lifetimes. Items declared with the static or externspecifier
have global lifetimes.
1.1
Auto
A variable declared
inside a function without any storage class specification, is by default an
automatic variable. They are created when a function is called and are
destroyed automactically when the function exits. Automatic variables can also
be called local variables because they are local to function. By default
assigned garbage value by compiler:
Void
main()
{
int detail;
Or
Auto int detail; //Both are same
}
1.2
Register
Register variable informs
the compiler to store the variable in register instead of memory. Register
variable has faster access than normal variable. Frequently used variables are
kept in register. Only few variables can be placed inside register. We can
never get address of variables stored in register.
register
int number;
1.3
Static
A static variable tells
the compiler to persist the variable until the end of program. Instead of
creating and destroying a variable every time when it comes into and goes out
of scope, static is initialized only once and remains into existence till end
of program. A static variable can either be internal or external depending upon
the place of declaration. Scope of internal
static variable remains inside the functional in which it is defined.
External static variable remain restricted to scope of file in which they are
declared.
They are assigned 0(zero)
as default value by the complier.
Example 1:
void test():
void test():
main()
{
test() ;
test() ;
test() ;
}
void
test()
{
static int a=0;
a = a+1;
printf (“%d\t”,a);
}
Output:
1 2 3
Example 2:
int GLOBAL ;
int function( void )
{
int LOCAL ;
static int *lp =
&LOCAL; /* Illegal initialization
*/
static int *gp =
&GLOBAL; /* Legal
initialization */
register int *rp =
&LOCAL; /* Legal initialization */
}
In C, if an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a NULL pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.
1.4
extern
The extern keyword is
used before a variable to inform the compiler that this variable is declared
somewhat else. The extern declaration does not allocate storage for variables.
2.
C Type Specifiers / Data Types
Data Type specifies how we enter data into our
programs and what type of data we enter.
Primary Data types: These are fundamental data types
in C namely integer(int), floating(float) and void.
Derived Data types / Extended Data types: Derived
data types are like arrays, structures & Pointers.
Void
The void
type specifies that no value is available. It is used in three kinds of
situations:
S.N.
|
Types and Description
|
1
|
Function returns as void
There are various functions in C which do not return value or you can say they return void. A function with no return value has the return type as void. For example void exit (int status); |
2
|
Function arguments as void
There are various functions in C which do not accept any parameter. A function with no parameter can accept as a void. For example, int rand(void); |
3
|
Pointers to void
A pointer of type void * represents the address of an object, but not its type. For example a memory allocation function void *malloc( size_t size ); returns a pointer to void which can be casted to any data type. |
Void Pointers: Suppose we
have declare integer pointer, character pointer and float pointer then we need
to declare 3 pointer variables. Instead of declaring different types of pointer
variable it is feasible to declare single pointer variable which can act as
integer pointer, character pointer.
void
*ptr;
char
cnum;
int
inum;
ptr
= &cnum; //ptr has address of character data
ptr
= &inum; //ptr has address of integer data
ptr
= &fnum; //ptr has address of float data
Void pointer declaration
is shown above. When have declared 3 variables of integer, character &
float type. When we assign address of integer to void pointer, pointer will
become Integer pointer. When we assign address off Character Data type pointer
it will become Character Pointer. Similarly we can assign address of any data
type to the void pointer. It is capable of storing address of any data type.
Integer type:
Integers are used to
store whole numbers.
Floating type:
Floating types are used
to store real numbers.
Character type:
Character types are used
to store characters value.
3.
Type Qualifier: The keywords which are used to modify
the properties of a variable are called type qualifiers.
Standard
C language recognizes the following two qualifiers:
- const
- volatile
The const qualifier is used to tell C that the variable
value cannot change after initialization.
const float pi=3.14159;
Now pi cannot be changed at a later time within the
program.
The volatile qualifier declares a data type that can have its value
changed in ways outside the control or detection of the compiler (such as a
variable updated by the system clock or by another program). This prevents the
compiler from optimizing code referring to the object by storing the object's
value in a register and re-reading it from there, rather than from memory, where
it may have changed.
4.
Declarators and variable declarations
4.1
Simple Variables:
The
declaration of a simple variable, the simplest form of a direct declarator,
specifies the variable's name and type. It also specifies the variable's
storage class and data type.
Storage
classes or types (or both) are required on variable declarations. Untyped
variables (such as var;) generate warnings.
You can use
a list of identifiers separated by commas (,) to specify several
variables in the same declaration. All variables defined in the declaration
have the same base type. For example:
int x,
y; /* Declares two simple
variables of type int */
int const z
= 1; /* Declares a constant value of type int */
The
variables x and y can hold any value in the set defined by
the int type for a particular implementation. The simple
object z is initialized to the value 1 and is not modifiable.
4.2
Arrays
An
"array declaration" names the array and specifies the type of its
elements. It is possible to make arrays whose elements are basic types. Thus we
can make an array of 10 integers with the declaration.
int x[10];
The square
brackets mean subscripting; parentheses are used only for function references.
Array indexes begin at zero, so the elements of x are:
Thus Array
are special type of variables which can be used to store multiple values of
same data type. Those values are stored and accessed using subscript or index.
Arrays
occupy consecutive memory slots in the computer's memory.
x[0], x[1], x[2], ..., x[9]
int array [8] = {2, 4, 6, 8, 10, 12, 14, 16};
Two Dimensional Arrays
C language
supports multidimensional arrays. The simplest form of the multidimensional
array in the two dimensional array. Two dimensional array is declared as
follows,
type array-name[row-size][column-size]
Example:
int a[3][4];
a[0][0] a[0][1] a[0][2]
a[0][3]
a[1][0] a[1][1] a[1][2]
a[1][3]
a[2][0] a[2][1] a[2][2]
a[2][3]
4.3
Pointers
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.
int *ip;
/* pointer to an integer */
double *dp; /* pointer to a double */
float *fp;
/* pointer to a float */
char *ch
/* pointer to a character */
4.4
Enumeration
An
enumeration consists of a set of named integer constants. An enumeration type
declaration gives the name of the (optional) enumeration tag and defines the
set of named integer identifiers (called the "enumeration set,"
"enumerator constants," "enumerators," or "members").
A variable with enumeration type stores one of the values of the enumeration
set defined by that type.
enum identifier { enumerator-list }
Enumerations
provide an alternative to the #define preprocessor directive
with the advantages that the values can be generated for you and obey normal
scoping rules.
The
following rules apply to the members of an enumeration set:
- An enumeration set can contain
duplicate constant values. For example, you could associate the value 0
with two different identifiers, perhaps
named null and zero, in the same set.
- The identifiers in the
enumeration list must be distinct from other identifiers in the same scope
with the same visibility, including ordinary variable names and
identifiers in other enumeration lists.
- Enumeration tags obey the normal
scoping rules. They must be distinct from other enumeration, structure,
and union tags with the same visibility.
Examples:
enum DAY /*
Defines an enumeration type */
{
saturday, /* Names day and declares a */
sunday = 0, /* variable named workday with */
monday, /* that type */
tuesday,
wednesday, /* wednesday is associated with 3 */
thursday,
friday
} workday;
The value 0
is associated with saturday by default. The identifier sunday is
explicitly set to 0. The remaining identifiers are given the values 1 through 5
by default.
4.5
Structures
Structure is user defined data type available in C
programming, which allows you to combine data items of different kinds.
Defining a Structure
To define a structure, you must use the struct statement.
The struct statement defines a new data type, with more than one member for
your program. The format of the struct statement is this:
struct [structure tag]
{
member
definition;
member
definition;
...
member
definition;
} [one or more structure variables];
The structure tag is optional and each member definition
is a normal variable definition, such as int i; or float f; or any other valid
variable definition. At the end of the structure's definition, before the final
semicolon, you can specify one or more structure variables but it is optional.
Here is the way you would declare the Book structure:
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
Accessing Structure Members
To access any member of a structure, we use the member access
operator (.). The member access operator is coded as a period between the
structure variable name and the structure member that we wish to access. You
would use struct keyword to define variables of structure
type. Following is the example to explain usage of structure:
#include <stdio.h>
#include <string.h>
struct Books
{
char
title[50];
char
author[50];
char
subject[100];
int book_id;
};
int main( )
{
struct
Books Book1; /* Declare Book1 of
type Book */
struct
Books Book2; /* Declare Book2 of
type Book */
/*
book 1 specification */
strcpy(
Book1.title, "C Programming");
strcpy(
Book1.author, "Nuha Ali");
strcpy(
Book1.subject, "C Programming Tutorial");
Book1.book_id
= 6495407;
/*
book 2 specification */
strcpy(
Book2.title, "Telecom Billing");
strcpy(
Book2.author, "Zara Ali");
strcpy(
Book2.subject, "Telecom Billing Tutorial");
Book2.book_id
= 6495700;
/*
print Book1 info */
printf(
"Book 1 title : %s\n", Book1.title);
printf(
"Book 1 author : %s\n", Book1.author);
printf(
"Book 1 subject : %s\n", Book1.subject);
printf(
"Book 1 book_id : %d\n", Book1.book_id);
/*
print Book2 info */
printf(
"Book 2 title : %s\n", Book2.title);
printf(
"Book 2 author : %s\n", Book2.author);
printf(
"Book 2 subject : %s\n", Book2.subject);
printf(
"Book 2 book_id : %d\n", Book2.book_id);
return
0;
}
When the above code is compiled and executed, it produces the following
result:
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
4.6
Unions
A union is a special data type available in C that
enables you to store different data types in the same memory location. You can
define a union with many members, but only one member can contain a value at
any given time. Unions provide an efficient way of using the same memory
location for multi-purpose.
Defining a Union
To define a union, you must use the union statement.
The union statement defines a new data type, with more than one member for your
program. The format of the union statement is as follows:
union [union tag]
{
member definition;
member definition;
...
member definition;
} [one or more union variables];
The union tag is optional and each member
definition is a normal variable definition, such as int i; or float f; or any
other valid variable definition. At the end of the union's definition, before
the final semicolon, you can specify one or more union variables but it is
optional. Here is the way you would define a union type named Data which has
the three members i, f, and str:
union Data
{
int i;
float f;
char str[20];
} data;
Now, a variable of Data type can store an
integer, a floating-point number, or a string of characters. This means that a
single variable ie. same memory location can be used to store multiple types of
data. You can use any built-in or user defined data types inside a union based on
your requirement.
The memory occupied by a union will be large enough to hold
the largest member of the union. For example, in above example Data type will
occupy 20 bytes of memory space because this is the maximum space which can be
occupied by character string.
Accessing Union Members
To access any member of a union, we use the member
access operator (.). The member access operator is coded as a period
between the union variable name and the union member that we wish to access.
You would use union keyword to define variables of union type.
Following is the example to explain usage of union:
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[20];
};
int main( )
{
union Data data;
data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");
printf( "data.i : %d\n", data.i);
printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);
return 0;
}
When the above code is compiled and executed, it produces the
following result:
data.i : 1917853763
data.f :
4122360580327794860452759994368.000000
data.str : C Programming
Here, we can see that values of i and f members
of union got corrupted because final value assigned to the variable has
occupied the memory location and this is the reason that the value if str member
is getting printed very well. Now let's look into the same example once again
where we will use one variable at a time which is the main purpose of having
union:
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[20];
};
int main( )
{
union Data data;
data.i = 10;
printf( "data.i : %d\n", data.i);
data.f = 220.5;
printf( "data.f : %f\n", data.f);
strcpy( data.str, "C Programming");
printf( "data.str : %s\n", data.str);
return 0;
}
When the above code is compiled and executed, it produces the
following result:
data.i : 10
data.f : 220.500000
data.str : C Programming
Here, all the members are getting printed very well because
one member is being used at a time.
Sources:
5. http://www.geeksforgeeks.org/g-fact-53/
5.
Typedef
Type
definitions make it possible to create your own variable types. The C
programming language provides a keyword called typedef, which you can use to
give a type a new name. Following is an example to define a term BYTE for
one-byte numbers:
typedef unsigned char BYTE;
After
this type definitions, the identifier BYTE can be used as an abbreviation for
the type unsigned char, for example:.
BYTE b1, b2;
In
the following example we will create a type definition called “intpointer” (a
pointer to an integer):
#include<stdio.h>
typedef
int *int_ptr;
int
main()
{
int_ptr
myvar;
return
0;
}
It
is also possible to use type definitions with structures. The name of the type
definition of a structure is usually in uppercase letters. Take a look at the
example:
#include<stdio.h>
typedef
struct telephone
{
char
*name;
int
number;
}TELEPHONE;
int
main()
{
TELEPHONE
index;
index.name
= "Jane Doe";
index.number
= 12345;
printf("Name:
%s\n", index.name);
printf("Telephone
number: %d\n", index.number);
return
0;
}
Note: The word struct is not needed before TELEPHONE index;
typedef vs #define
The #define is
a C-directive which is also used to define the aliases for various data types
similar totypedef but with following differences:
- The typedef is
limited to giving symbolic names to types only where as #define can
be used to define alias for values as well, like you can define 1 as ONE
etc.
- The typedef interpretation is performed by the compiler where as #define statements are processed by the pre-processor.
Sources:
No comments:
Post a Comment