100% found this document useful (1 vote)
556 views25 pages

Structures in C

The document discusses structures, unions, and pointers in C programming. It defines structures as user-defined data types that can hold heterogeneous data elements under a single name. Structures are defined with the struct keyword and accessed using the dot operator. Unions are similar but allocate a single shared memory location for member fields. Pointers hold the address of another variable and can be used to return multiple values from a function. Pointers are declared with a data type followed by an asterisk and are dereferenced using the asterisk operator to access the value at a given address.

Uploaded by

Monisha Cyril
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
556 views25 pages

Structures in C

The document discusses structures, unions, and pointers in C programming. It defines structures as user-defined data types that can hold heterogeneous data elements under a single name. Structures are defined with the struct keyword and accessed using the dot operator. Unions are similar but allocate a single shared memory location for member fields. Pointers hold the address of another variable and can be used to return multiple values from a function. Pointers are declared with a data type followed by an asterisk and are dereferenced using the asterisk operator to access the value at a given address.

Uploaded by

Monisha Cyril
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

INDIRA GANDHI COLLEGE OF ARTS AND SCIENCE

DEPARTMENT OF COMPUTER SCIENCE


PROGRAMMING IN C
UNIT IV - NOTES
STRUCTURES
What is a structure?
 It’s a User defined data type
 Can hold many data objects of different data types (heterogeneous) may contain the
integer elements, float elements and character elements. etc.
 Collection of variables under single name
 Can conveniently used to represent a record

Give syntax for structure definition


Syntax:
struct [structure name]
{
Data _type memeber_name[, member name 2,..];
Data _type memeber_name[, member name 2,..];
}[variable name];
Example:
struct books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;

Define structure declaration.


 Variables/constants for structure types can be declared at definition or after
definition
 struct key word mandatory
 A structure must end with a semicolon
Example: Declare variables Book1,Book2 of type Books
struct Books Book1;
struct Books Book2;

The rules for declaring a structure


 A structure must end with a semicolon
 struct key word mandatory
 Each structure member must be terminated.
 The structure variable must be accessed with dot(.) operator.
 Structure declaration list (structure members):
o Can have char, float, double, int, array[], pointer* other structure types
o Cannot have void, function type, same structure instance
o Can have pointer to an instance of itself which is called as self referential
structures.

How structure elements can be accessed?


 Structure members can be accessed using
1. Direct member access operator/dot operator
• Represented as (.)
• It’s a Binary Operator
1
• Syntax: Structure_name.structure_member_name

2. Indirect member access operator/arrow operator


• Represented as →
• It’s to access structure members by the pointer to the structure
• Syntax: Pointer_to_Structure→structure_member_name

Difference between array and structures.


Array Structures
Array elements are of same data types Structure elements are of different data
(homogeneous). type(heterogeneous).
Array allocates static memory and uses index Structures allocate dynamic memory and uses
/ subscript for accessing elements of the (.) operator for accessing the member of a
array. structure.
Array is a pointer to the first element of it. Structure is not a pointer
An array is a derived data type A structure is a user-defined data type
The individual data members of an array can The individual data members of the structure
be initialized. cannot be initialized.
Array elements can be accessed by indexing Structure members can be accessed using dot
the array name. operator / arrow operator
Example for Array Declaration Example for Structure Declaration
int b1[3]; struct Books {
int a; char b;
}b1;

Array of Structures & Array within A Structure


#include <stdio.h>
struct student
{
char name[50];
int roll;
float marks;
} s[10];

int main()
{
int i;

printf("Enter information of students:\n");

// storing information
for(i=0; i<10; ++i)
{
s[i].roll = i+1;
printf("\nFor roll number%d,\n",s[i].roll);
printf("Enter name: ");
scanf("%s",s[i].name);
printf("Enter marks: ");
scanf("%f",&s[i].marks);
printf("\n");
}
printf("Displaying Information:\n\n");
// displaying information
2
for(i=0; i<10; ++i)
{
printf("\nRoll number: %d\n",i+1);
printf("Name: ");
puts(s[i].name);
printf("Marks: %.1f",s[i].marks);
printf("\n");
}
return 0;
}

UNIONS
A union is very similar to structures but for the difference in the keyword union instead of
struct. The major difference lies in the method of storage of values for the fields in the
memory. In struct data type, memory locations are created for every member in consecutive
locations. Hence the size of the struct data type is the sum of the number of bytes of all the
memory field. But in union data type, only one memory is created and it is shared by all the
member fields.

syntax for union definition


Syntax:
union [union name]
{
Data _type memeber_name[, member name 2,..];
Data _type memeber_name[, member name 2,..];
}[variable name];
Example:
union books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;

POINTERS
Pointer Basics
Variables in C are abstractions of memory, holding a value. That value is typed, defined by
a data type definition in the variable declaration. Eg. Int i.

A pointer is no different. A pointer is a variable whose value is an address, typed by its


declaration. Pointers "point to" a variable (memory) with a typed value by referencing that
variable, not by name, but by address.

What is a Pointer? How a variable is declared to the pointer?

Pointer is a variable which holds the address of another variable.


x c
Pointer declaration:
datatype *variable-name; 2000 5
Example:
int *x, c=5; x=&c; Addr: 1000 2000
c
3
What are the uses of Pointers?
 Pointers are used to return more than one value to the function
 Pointers are more efficient in handling the data in arrays
 Pointers reduce the length and complexity of the program
 They increase the execution speed
 The pointers saves data storage space in memory

What are * and & operators means?


 * operator - value at the address[indirection/dereferencing operator]. The
indirection operator (*) accesses a value indirectly, through a pointer. The
operand must be a pointer value. The result of the operation is the value
addressed by the operand; that is, the value at the address to which its operand
points. The type of the result is the type that the operand addresses.
 & operator - address of operator [referencing operator]. It’s a pointer address
operator is denoted by ‘&’ symbol. When we use ampersand symbol as a prefix
to a variable name ‘&’, it gives the address of that variable.

How can you return more than one value from a function?
A function returns only one value. By using pointer we can return more than one
value. If we want the function to return multiple values of same data types, we could return
the pointer to array of that data types.

Pointer Declarations

Pointers are declared to point to a typed value. This is the syntax of a declaration:

datatype *variable_name

Here are some examples:

int *ptr1;
float *ptr2;
char *ptr3;

These declare ptr1 to hold the address of an integer, ptr2 to hold the address of a floating
point number, and ptr3 to hold the address of a character.

Like all variables, pointer variables do not have a value simply by being declared. That
fact might seem intuitive for other data types, but it's hard to remember for pointers. In the
above examples, the variables are meant to contain the address of other variables, but they
have not been initialized yet.

Declaration Notation
At first glance, the notation used to declare pointers might seem wrong. Since a pointer
variable points to another variable of the declared data type, you might expect the
declaration to look like this:

int* ptr1;

Instead, the * symbol is associated with the variable name in the declaration. This is
intentional. If we associate the * symbol with the variable name, we can declare a list of
variable names, some of which are not pointers. Here is an example:
int *ptr1, width, height, *mem;
4
Note that not everything in the list is a pointer. This is possible only if we associate
the * with the variable name. If we were to use the notation int* ptr1, mem; only the
first item in the list would be a pointer.

Variables and Addresses

If pointers contain addresses, there should be a way to give them an address as a value. All
variables have an address, a designation of where they are stored in memory. We can
derive the address of a variable by placing a "&" symbol in front of the variable name.
Here is an example:

int distance = 10;


int *ptri = &distance;
printf("%u\n", ptri);

The variable ptri is assigned the address of the variable distance as its value. The value
of distance is not changed.

Now if we were to print the value of ptri, we would get a large number that really makes
no sense to us, but makes sense to the computer runtime system. The printf function call
above might print this as its value:
3216074448

That value makes sense to the computer, but it is of no use to programmers. Knowing the
address does not help us work with the pointer or what it points to.

Dereferencing a Pointer

Once a pointer has an address of a variable name, we can use it to work with the variable it
references. To do this, we have to dereference the pointer, that is, get to the variable or
memory it points to.

Dereferencing a pointer uses the same asterisk notation that we used to declare a pointer.
Consider the following example.

int payment = 10;


int *p = &payment;

*p = 15;

This code starts by assigning the value 10 to the variable payment . Then the
pointer p takes the address of payment as its value. The third statement
changes payment to 15 by actually assigning the value 15 to the variable to which p points.
The *p in the statement is a dereference.

Using the same syntax to declare pointers and to dereference pointers can be a bit
confusing, especially if the declaration is used with an initial value, like in the above
example. Unfortunately, you just have to remember the difference between declaration and
dereferencing.
Let's look at one more example of dereferencing.

int distance = 250, fuel = 10;


5
float economy1, economy2;
int *pd, *pf;

pd = &distance;
*pd = *pd + 10;
pf = &fuel;
*pf = *pf +5;
economy1 = distance / fuel;
*(&economy2) = economy1;

In this example, the variable distance is set to 250 and incremented by 10 by


dereferencing the pointer pd. Likewise, the variable fuel is set to 10, then incremented
by 5 by dereferencing the pointer pf. The last statement is there to show that you can even
dereference an address operator. By dereferencing what the address of economy2 points to,
we just reference the variable economy2.

Pointers and Memory Allocation

Allocating Memory
While you can work with declared variables using the "&" operator, you can also create
memory space while a program is executing and allow a pointer to reference it. This
memory space does not even need a name associated with it.

You create space in memory using the malloc function. To create space, you need to
know the type of space you want to create and the size in bytes of that space. Fortunately,
you don't have to know the size of everything in C; you can use an operator to compute
that.

The sizeof operator will return the number of bytes its type parameter uses. For example,

sizeof(int)

should return the value 4: a variable declared to be of type int will take up 4 bytes in
memory.

Once we know the number of bytes we want to allocate, calling malloc with the right size
will create a space in memory of that size and will return the address of that space. So,
consider this example:

int *p = malloc(sizeof(int));

Here, we have allocated enough memory to store a single integer and returned the address
of that space to be assigned to the pointer p. Now, the only way to work with that space is
through the pointer. But if we use dereferencing correctly, this space can be used as if we
have a variable, because we do! We do indeed have a variable; it just does not have a name
associated with it.

Here's another example:


int *pa = malloc(5*sizeof(int));

6
In this allocation, we have created a space that is big enough to store 5 integers.

Since this space is contiguous, that is, created from sequential memory locations, we have
essentially created an array of 5 integers. We will examine this further, but we need to first
figure out how to access each integer in this space by doing arithmetic on pointers.

Pointers are typed in C. When a pointer is declared, the data type it points to is recorded.
As with other variables, if we try to assign values from incompatible types, errors will
result.

Pointer Arithmetic
We have said that a pointer contains an address into memory. If addresses are just
numbers, then we can do computations with them. Indeed, we can do pointer arithmetic in
an intuitive fashion.

As you might think, pointer arithmetic uses operators + and - to increment or decrement
addresses. However, to increment a pointer means to add enough to its value to move to
the next element of the data type to which it points. For example, if a pointer cont ains the
address of an integer, then adding one to that pointer means skipping 4 bytes to point to
the next integer. If the data type is larger, the increment will increase the pointer the
correct amount of bytes. Decrement works in an analogous way.

This is especially useful when a pointer points to the beginning of an allocated area in
memory. Let's say that we have code that just allocated space in memory for 20 integers:

int *bigspace = malloc(20 * sizeof(int));


*bigspace = 10;

By dereferencing the pointer, we gain access to the first integer in the space. The rest of
the integers are accessible through pointer arithmetic. Consider the following code:

*(bigspace + 1) = 20;
*(bigspace + 2) = 30;

This code assigns the values 20 and 30 to the the second and third integers in the space,
respectively. This is how we would access all integers in the allocated space.

There's a few notes we need to make about pointer arithmetic.

 The result of pointer arithmetic is a pointer. As seen in the example above, we do the
arithmetic inside the parentheses and then treat the result like it was a declared pointer. In
the example above, we dereferenced the result of the addition and it worked.
 As with all expressions, the above example simply computes where the next integer is
located, but does not change the pointer itself.
 There is no way to derive where a pointer points in the allocated space. We could get the
pointer's value, which is an address, but that would not give us much information about
which allocation element a pointer points to.

Let's walk through one more example.

7
long *bigints = malloc(100 * sizeof(long));
for (int i=0; i<100; i++, bigints++) *bigints = 0;
bigints -= 100;

In this example, we allocate 100 long integers and initializing each long integer in the
space to the value 0. Then we "rewind" the pointer by
subtracting 100*sizeof(long) from it. It is our only way to access all the long integers in
the allocated space and we must be careful to work with the pointer so it accurately points
to the elements we need.

Pointers and Arrays


We have defined arrays as a collection of elements of the same type, organized in
sequence so that we can reference them with an integer index. We have also described
memory allocation as a way to create a collection of elements of the same type, placed
sequentially in memory. These two ideas are so very close that C treats them the same.

We will demonstrate that pointers are arrays and arrays are pointers.

Pointers and Array References

C allows the same syntax to be used for both arrays and pointers. Let's consider a previous
example:

int *bigspace = malloc(20 * sizeof(int));

We accessed and assigned values to memory in this way:

*bigspace = 10;
*(bigspace + 1) = 20;
*(bigspace + 2) = 30;

We could just as easily have used array reference syntax:

bigspace[0] = 10;
bigspace[1] = 20;
bigspace[2] = 30;

Declaring bigspace as an array also works:


int bigspace[20];

And both methods of accessing the memory space are still equally valid.

Pointers and arrays may be exchanged in assignment statements as well. For example,
consider the following:

int space1[20];
int *space2 = space1;

*space1 = 10;
space2[1] = 20;

8
The first two elements of the array space1 have been initialized to 10 and 20, respectively.
The reverse is true as well:

int *space2 = malloc(20 * sizeof(int));


int space1 = space2;

*space1 = 10;
space2[1] = 20;

This illustrates our point: pointers are arrays and arrays are pointers.

Are Pointers and Arrays Really the Same Thing?


If pointers are arrays and arrays are pointers, then why are there two different concepts?

Pointers and array are not the same thing and are really not treated the same by a C
compiler. The point we are making here is that array notation and pointer notation are
interchangeable.

There are indeed differences between the two structures. The sizeof function will return
different values for a pointer (which is a variable that fits into a memory word) and an
array (which is a collection of data). A C compiler will treat storage of dynamically
allocated memory differently than an array initialized as a string. They have similar uses,
but also different uses.

So, while it helps to be able to use notation that works for both, arrays and pointers are
really different types of data with a variety of different uses.

Pointer Arithmetic and Array Indicies

As we saw in the previous section, pointer arithmetic and using indicies and array notation
are interchangeable. We have also seen how to use pointer arithmetic to move pointers
through allocated memory space.

As declared and initialized to a memory space, pointers point to the base, the first element,
of that space. This is item number 0 in array notation. Whenever we add 1 to a pointer, the
system computes the size, in bytes, of the data type that the pointer points to and
increments that pointer the number of bytes that make up that data type. Thus, an
increment for the pointer is the same as an increment in array notation.

For example, consider this code:

short sa[10], *ps;


long sl[10], *pl;

ps = sa;
pl = sl;

Now, ps points to sa[0] and pl points to sl[0]. Now if we increment both pointers by 1,
like this:

ps++;
pl++;
9
ps points to sa[1] and pl points to sl[1]. Even though both pointers were incremented
by 1, the addresses were incremented by a different number of bytes.

If we wanted a pointer to start in the middle of an array, instead of the beginning, we


would need to use the address of a selected item from that array. For example, if we
wanted ps from the example above to point to sa[4], we would need to derive the address
of sa[4] like this:

ps = &sa[4];

Now, ps points into the array and not at the beginning.

Pointers and Multidimensional Arrays

Now let's consider how pointers interact with multidimensional arrays. The syntax starts to
get a bit clumsy, but if we remember how pointers work with memory, the syntax is easier
to understand.

Let's start with two dimensions: rows and columns. Remember that a two-dimensional
array is really just a big memory space, organized as rows and columns. If that's true, then
a pointer into that space could actually just work as we have described it so far. Here's an
example:

long table[10][20];
long *ptr = table;

This code describes a space comprised of 200 long integers. We could work with ptr as if
it was pointing into that 200 long integer space. We could
reference ptr[30] or (ptr+30) and it would work, referencing a long integer, 30 items
into that space.

However, if we are declaring an array to have two dimensions, then it makes sense to try
to use pointers in two dimensions. When we have an array of two dimensions, we can
think of it as an "array of arrays". Using one dimension references an entire array from that
collection. So referencing table[3] references an entire array at the 4th row of the table.

To use pointers with two dimensions, we need to think like this. If one pointer reference
points to an array, then we really need a double reference: one to the the array/row and one
more to get the item at the column in the array/row. Consider this type of declaration:

long table[10][20];
long **ptr = table;

Note the double asterisk: one for rows and one for columns. Now, it would be an error to
reference ptr[30] because there are not 30 rows in the table, only 10. In
addition, (ptr+5) skips over the first 5 arrays, or 100 long integers, giving us access to the
array at table[5].

The same works to other dimensional arrays. Three dimensions could work like this:
long bigtable[5][10][20];

10
long ***ptr;

Other dimensions work analogously.

Typed Pointers and Untyped Pointers


We have seen that, in C, pointers can be typed. The data type that a pointer points to
informs the compiler on how many bytes to increment a pointer's address when using
pointer arithmetic and how to work with pointers in situations where data types matter
(like computations or some types of parameters). For example, in this code:

float x, y, *pf;
int a, b, *pi;

we cannot mix pointers to floats and integers in the same situations we can't mix actual
floats and integers. For example:

*pf = 12.5;
a = 10;
pf = &a;
b = *pf + a;

The last line is an error, because it mixes a floating point number and an inte ger,
producing a floating point number, and tries to assign it to an integer.

There are situations where untyped pointers are appropriate. Untyped pointers are declared
to point to a "void" type and may point to values of any type. However, since they have no
data type themselves, in order to dereference such a pointer, we must tell the compiler
what it points to. Consider this example.

void main() {
int numbers[6] = {10, 20, 1, 5, 19, 50};
float average;

void *p;
p = &numbers[3];
p = &average;

average = computeAverage(numbers, 6);

printf("Average of these values is %f\n", *(float*)p);


}

In this code, assume that computeAverage computes the average of the integers in the
array and returns that value as a float (we saw this example in Chapter 7). First, note that
the pointer p takes an address of an integer variable, then takes the address of a float
variable, and that a compiler would think this is correct. Second, in the call to printf, we
had to inform the compiler that p was currently pointing to a float variable, and then we
could dereference it.

Untyped pointers are also useful as formal parameters to functions. Using a void type for a
pointer in a function specification allows flexibility in the actual parameter. Untyp ed
11
pointers can also be useful as return values; for instance, malloc returns an untyped
pointer. We will discuss these ideas further in the next section.

Pointers as Function Parameters


Pointers are the only way parameters can be changed in functions in a way that the caller
of the function can access.

We have said in Chapter 6 that functions use pass-by-value for function parameters. In
other words, values are copied from actual parameters to formal parameters when the call
is made, but not copied back when the function returns. This implies that it is impossible
to send changed values back to a function caller.

However, using pointers as parameters to functions makes this type of change possible. If
we send a pointer to memory to a function, any changes to the pointer itself will be
ignored, but the function can dereference the pointer and make changes to memory that the
pointer references. That memory is not part of the parameter list of the function and those
changes will be reflected back to the caller.

Let's consider the following example.

void swap_integers(int first, int second) {


int temp;
temp = first;
first = second;
second = temp;
}

Now, because C uses pass-by-value, calling this code like this will not swap anything:

int x = 10, y = 20;


swap_integers(x, y);

The variables x and y will retain the same values after the function call.

Now, let's change the parameters of swap_integers into pointers. The code would look
like this:

void swap_integers(int *first, int *second) {


int temp;
temp = *first;
*first = *second;
*second = temp;
}

Because the parameters are now pointers, we have to dereference them to get at the actual
values to be swapped. But now, since we are not changing the parameters, but rather the
memory to which they point, memory is changed.

We would call this function this way:


int x = 10, y = 20;
swap_integers(&x, &y);

12
And the values are actually swapped.

Can We Make "swap" Generic with void Pointers?

If we can use typed pointers in a swap_integers function, could we use untyped pointers
in a generic swap function? That is, by using "void" pointers, could we swap values
of any type?

The answer, unfortunately, is "NO". While we can certainly specify parameters that
are void *parameters, we cannot dereference a void pointer without knowing the data
type to which it points. In addition, because we assign a value to temp in the above code,
we must know what data types first and second point to, so the compiler knows how to
make the assignment.

NULL Pointers
We have stated that pointers contain memory addresses as their values. In addition to
addresses, pointers can have a "no address" value, called "null". This null value is actually
a special value (many compilers make this value 0, although it could be another special
value). Null values are unique; null pointers of any type are guaranteed to be equal.

Null pointers should not be confused with uninitialized pointers. Uninitialized pointers,
like uninitialized variables, have no defined value; they occupy space in memory and take
on whatever value was left there by the previous variable that occupied that space. Null
pointers have a specific null value; uninitialized pointers have an undefined value.

Null pointers typically signify the end of data or an error condition. Dereferencing a null
pointer will typically cause a program-crashing error.

Freeing up Memory

Dynamically creating memory with malloc is a great way to only take up the memory that
your program needs. Memory on a Pebble smartwatch is limited, and using pointers in this
way is frugal.

To continue this frugality, memory space that is allocated by your program must also be
deallocated by your program. To deallocate memory that was allocated with malloc, use
the free function call. Here's an example of allocating and immediately freeing up
memory:

long *racing = malloc(40 * sizeof(long));

free(racing);

It's as easy as that. It should be done in your program as soon as memory space is not
needed.
When freeing memory space, you need to be aware of certain rules:

 You cannot free memory that was not allocated by malloc. For example, if you assign a
pointer the address of a declared variable, freeing that pointer's memory will cause an

13
error. Declared variables are allocated differently than dynamically allocated memory
space.
 You cannot free a null pointer. Null pointers are pointers with "no address" values and
freeing them will cause an error.
 You cannot free uninitialized pointers. These pointers do not point to anything and trying
to free them will cause a program error.

Sometimes, memory is allocated by function calls within functions. That kind of allocation
is usually freed up by a companion function to the function that allocated the space. (See
below in "Pointers and Pebble Programming" for examples.)

How to Avoid Messy Coding with Pointers


Pointers are notorious for creating messy, confusing code. Here are some examples:

intar[i];
*(intar+i);
*(i+intar);

These are all equivalent references; they can be used with either int intar[10] or int
*intar = malloc(10*sizeof(int)); declarations. Here's another example:
char *c = "Hello World";
while (*c) printf("%c", *c++);

As we will see in the next chapter, strings in C are arrays of characters, ending with a
character with a 0 value (a "null" character). Knowing this, the above code will print each
character of a string, incrementing to the next character for the next iteration of the loop.
Here's one more example:

int main()
{
int i, sum;
int *ptr = malloc(5 * sizeof(int));

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


*(ptr + i) = i;

sum = *ptr++;
sum += (*ptr)++;
sum += *ptr;
sum += *++ptr;
sum += ++*ptr;

printf("Sum = %d\n", sum);


}

Running this example will print the value 8, when the intention is to print the value 10.
The confusion here is the various ways that pointer arithmetic has been done.

Here a few tips to remember to avoid confusion with pointers.

14
1. Never forget to initialize pointers. This is a simple rule, but it is very confusing when a
pointer uses old values.
2. Using array syntax with pointers can be a lot clearer than pointer syntax. This is especially
true of multidimensional arrays and array spaces.
3. Be painfully clear when using pointer arithmetic. Using shortcut arithmetic with
dereferencing can be very confusing, as we see in the examples above.
4. When using memory allocation, always use the most flexible and meaningful expressions.
Calling malloc(16) is not very expressive, but using malloc( 4 * sizeof(int) ) is much more
informative.

What is the difference between an array and pointer?


Array Pointer
Its a data structure that stores elements of It’s a variable that stores address of another
same data type in contiguous memory variable
locations
Array declaration: int a[6]; Pointer declaration: int *a;
Memory allocation is static Memory allocation can be dynamic
Array can be initialized at definition. Pointers can’t be initialized at definition
Example
int num[] = { 2, 4, 5}
Array elements are accessed using Pointers variables can be accessed using
subscripts indirection operator(*)

CHARACTER AND STRINGS


Basics of the Char Types

To declare a variable of type character we use the keyword char. - A single character stored in one
byte.
For example: char c;
To assign, or store, a character value in a char data type is easy - a character variable is just a symbol
enclosed by single quotes. For example, if c is a char variable you can store the letter A in it using the
following C statement: c='A';
Notice that you can only store a single character in a char variable. Later we will be discussing using
character strings, which has a very real potential for confusion because a string constant is written
between double quotes. But for the moment remember that a char variable is 'A' and not "A".
Reading Values for Character variables..
Type 1: scanf("%c", &c);
Type 2: c=getchar();
Displaying Values for Character variables..
Type 1: printf("%c", c);
Type 2: putchar(c);
Example

#include <stdio.h>
void main()
{
char ch, a;
printf("Enter Character: ");
ch=getchar();
a = '!';
putchar(ch);
15
printf("%c",a);
}
Output

Enter Character : M

M!

The C language features a lot of functions designed to test or manipulate individual characters. The
functions are all defined in the ctype.h header file. To use the functions, the ctype.h header file must
be included in your source code:

#include <ctype.h>

CTYPE functions fit into two categories: testing and manipulation.

Function Returns TRUE When ch is


isalnum(ch) A letter of the alphabet (upper- or lowercase) or a number
isalpha(ch) An upper- or lowercase letter of the alphabet
isascii(ch) An ASCII value in the range of 0 through 127
isblank(ch) A tab or space or another blank character
iscntrl(ch) A control code character, values 0 through 31 and 127
isdigit(ch) A character 0 through 9
isgraph(ch) Any printable character except for the space
ishexnumber(ch) Any hexadecimal digit, 0 through 9 or A through F (upper- orlowercase)
islower(ch) A lowercase letter of the alphabet, a to z
isnumber(ch) See isdigit()
isprint(ch) Any character that can be displayed, including the space
ispunct(ch) A punctuation symbol
isspace(ch) A white-space character, space, tab, form feed, or an Enter,
for example
isupper(ch) An uppercase letter of the alphabet, A to Z
isxdigit(ch) See ishexnumber()
Function Returns
toascii(ch) The ASCII code value of ch, in the range of 0 through 127
tolower(ch) The lowercase of character ch
toupper(ch) The uppercase of character ch
Generally speaking, testing functions begin with is, and conversion functions begin with to.

Every CTYPE function returns an int value. For the functions that return logical TRUE or FALSE
values, FALSE is 0, and TRUE is a non-zero value.

Howt to test characters

The CTYPE functions come in most handy when testing input, determining that the proper
information was typed, or pulling required information out of junk. The code in Text Statistics
illustrates how a program can scan text, pluck out certain attributes, and then display a summary of
that information.

TEXT STATISTICS

#include <stdio.h>
#include <ctype.h>

16
int main()
{
char phrase[] = "When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to assume among the
powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God
entitle them, a decent respect to the opinions of mankind requires that they should declare the causes
which impel them to the separation.";
int index,alpha,blank,punct;
alpha = blank = punct = 0;
/* gather data */
index = 0;
while(phrase[index])
{
if(isalpha(phrase[index]))
alpha++;
if(isblank(phrase[index]))
blank++;
if(ispunct(phrase[index]))
punct++;
index++;
}

printf(“\nNumber of Alphabets=%d”,alpha);

printf(“\nNumber of Blanks=%d”,blank);

printf(“\nNumber of Punctuations=%d”,punct);

STRINGS

In C programming, array of characters is called a string. A string is terminated by a null character /0.
For example:

"c string tutorial"

Here, "c string tutorial" is a string. When, compiler encounter strings, it appends a null character /0 at
the end of string.

Declaration of strings

Before we actually work with strings, we need to declare them first.

Strings are declared in a similar manner as arrays. Only difference is that, strings are of char type.

Using arrays

char s[5];

Using pointers

Strings can also be declared using pointer.

char *p;

17
Initialization of strings

In C, string can be initialized in a number of different ways.

For convenience and ease, both initialization and declaration are done in the same step.

Using arrays

char c[] = "abcd";

OR,

char c[50] = "abcd";

OR,

char c[] = {'a', 'b', 'c', 'd', '\0'};

OR,

char c[5] = {'a', 'b', 'c', 'd', '\0'};

Using pointers

String can also be initialized using pointers as:

char *c = "abcd";

Reading Strings from user

You can use the scanf() function to read a string like any other data types.

However, the scanf() function only takes the first entered word. The function terminates when it
encounters a white space (or just space).

Reading words from user

char c[20];

scanf("%s", c);

Example #1: Using scanf() to read a string

Write a C program to illustrate how to read string from terminal.

#include <stdio.h>
int main()
{
char name[20];
printf("Enter name: ");
scanf("%s", name);
printf("Your name is %s.", name);
return 0;
}
Output

18
Enter name: Dennis Ritchie

Your name is Dennis.

Here, program ignores Ritchie because, scanf() function takes only a single string before the white
space, i.e. Dennis.

Reading a line of text

An approach to reading a full line of text is to read and store each character one by one.

Example #2: Using getchar() to read a line of text

1. C program to read line of text character by character.

#include <stdio.h>
int main()
{
char name[30], ch;
int i = 0;
printf("Enter name: ");
while(ch != '\n') // terminates if user hit enter
{
ch = getchar();
name[i] = ch;
i++;
}
name[i] = '\0'; // inserting null character at end
printf("Name: %s", name);
return 0;
}
In the program above, using the function getchar(), ch gets a single character from the user each time.

This process is repeated until the user enters return (enter key). Finally, the null character is inserted at
the end to make it a string.

This process to take string is tedious.

Example #3: Using standard library function to read a line of text

2. C program to read line of text using gets() and puts()

To make life easier, there are predefined functions gets() and puts in C language to read and display
string respectively.

#include <stdio.h>
int main()
{
char name[30];
printf("Enter name: ");
gets(name); //Function to read string from user.
printf("Name: ");
puts(name); //Function to display string.
return 0;

19
}
Both programs have the same output below:

Output

Enter name: Tom Hanks

Name: Tom Hanks

Find the Frequency of Characters


#include <stdio.h>
int main(){
char c[1000],ch;
int i,count=0;
printf("Enter a string: ");
gets(c);
printf("Enter a character to find frequency: ");
scanf("%c",&ch);
for(i=0;c[i]!='\0';++i)
{
if(ch==c[i])
++count;
}
printf("Frequency of %c = %d", ch, count);
return 0;
}
Output
Enter a string: This website is awesome.
Enter a character to find frequency: e
Frequency of e = 4
String handling functions

Strings handling functions are defined under "string.h" header file, i.e, you have to include the code
below to run string handling functions.

#include <string.h>

There are various string operations you can perform manually like: finding the length of a string,
concatenating (joining) two strings etc.

Few commonly used string handling functions are discussed below:

Function Work of Function


strlen() Calculates the length of string
strcpy() Copies a string to another string
strcat() Concatenates(joins) two strings
strcmp() Compares two string
strlwr() Converts string to lowercase
strupr() Converts string to uppercase
Syntax of strlen()
temp_variable = strlen(string_name);
Function strlen() returns the value of type integer.

20
Syntax of strcpy()
strcpy(destination,source);
Here, source and destination are both the name of the string. This statement, copies the content of
string source to the content of string destination.

Example of strcpy()
#include <stdio.h>
#include <string.h>
int main(){
char a[10],b[10];
printf("Enter string: ");
gets(a);
strcpy(b,a); //Content of string a is copied to string b.
printf("Copied string: ");
puts(b);
return 0;
}
Output
Enter string: Programming Tutorial
Copied string: Programming Tutorial
C strcat() Prototype

It takes two arguments, i.e, two strings or character arrays, and stores the resultant concatenated string
in the first string specified in the argument.

Example: C strcat() function

#include <stdio.h>
#include <string.h>
void main()
{
char str1[] = "This is a", str2[] = "program";
//concatenates str1 and str2 and resultant string is stored in str1.
strcat(str1,str2);
puts(str1);
puts(str2);
}
Output

This is a program

program

strcmp() Prototype

21
The strcmp() function takes two strings and return an integer.

The strcmp() compares two strings character by character. If the first character of two strings are
equal, next character of two strings are compared. This continues until the corresponding characters of
two strings are different or a null character '\0' is reached.

Return Value from strcmp()

Return Value Remarks


0 if both strings are identical (equal)
negative if the ASCII value of first unmatched character is less than
second.
Defined in Header File: <string.h>

Syntax of strcmp()

temp_varaible=strcmp(string1,string2);

Example of strcmp()

#include <stdio.h>
#include <string.h>
int main(){
char str1[30],str2[30];
printf("Enter first string: ");
gets(str1);
printf("Enter second string: ");
gets(str2);
if(strcmp(str1,str2)==0)
printf("Both strings are equal");
else
printf("Strings are unequal");
return 0;
}
Output

Enter first string: Apple

Enter second string: Apple

Both strings are equal.

gets() and puts()

Functions gets() and puts() are two string functions to take string input from the user and display it
respectively.~

#include<stdio.h>

int main()

char name[30];
printf("Enter name: ");
gets(name); //Function to read string from user.
printf("Name: ");

22
puts(name); //Function to display string.
return 0;
}
Note: Though, gets() and puts() function handle strings, both these functions are defined in "stdio.h"
header file.

To Copy String Manually


#include <stdio.h>
int main()
{
char s1[100], s2[100], i;
printf("Enter string s1: ");
scanf("%s",s1);
for(i=0; s1[i]!='\0'; ++i)
{
s2[i]=s1[i];
}
s2[i]='\0';
printf("String s2: %s",s2);
return 0;
}
Output
Enter String s1: program
String s2: program

FORMATTED AND UNFORMATTED I/O FUNCTION


In C there are various input/output functions (library functions) that can be used in a
program by writing function name followed by list of arguments enclosed in parenthesis and
prototype/function declaration of these functions are found in header files.
The header file required by input/output functions are present mostly stdio.h and conio.h
which is included in program using #include statement
Function Formatted Unformatted
Input scanf( ), fscanf( ) getchar( ),gets( ),getch( ),getche( )
Output printf( ),fprintf( ) putchar( ), puts( ), putch( )

FORMATTED I/O FUNCTIONS


(i) scanf( )
 Function prototype is found in stdio.h header file
 Reads data from standard input device at runtime
 Uses format specifiers (%d,%s,%c etc)
Synatx: scanf (“format specifiers”, address list);
Example: scanf(“%s %d %f”,name,&rollno,&marks);
 & address operator not required for strings (string variables already point to memory
location)
 %s stops reading characters on encountering white space. Eg: Sam Paul will be read as Sam
only
(ii) printf()
 Function prototype is found in stdio.h header file
 It displays numerical values, characters, strings on output devices
23
 Uses format specifiers (%d,%s,%c etc)
Synatx: printf (“format specifiers”, print list);
Example: printf(“Name: %s,Roll No: %d, Marks: %f”,name,rollno,marks);

UNFORMATTED I/O FUNCTIONS


(i) getchar( )
 Function prototype is found in stdio.h header file
 It reads a character from keyboard and returns ASCII code of read character runctime
 To read sequence of charcters getchar ( ) function can be called repeatedly
Syntax: char variable_name = getchar( );
Example:
char grade;
grade=getchar( );
(ii) gets( )
 Function prototype is found in stdio.h header file
 It is used to accept string(set of characters) from user at runtime
 Its a buffered input function, does not stop reading on encountering white space
(iii) getch( )
 Function prototype is found in conio.h header file
 It reads single character directly from keyboard without printing it on screen
 Its an unbuffered input function (will not wait for any key/Enter Key for processing
Syntax: variable_name = getch( );
Example:
char grade;
grade=getch( );
(iv) putchar( ),putch( )
 Function prototype of putchar( ) is found in stdio.h header file, for putch( ) its found in
conio.h header file
 Both the functions print single character on screen
 A string can be printed by iteratively using these functions
Syntax: putchar(variable_name) ;
putch(variable_name) ;
Example:
char grade1=’A’,grade2=’S’ ;
putchar(grade1);
putch(grade2);
(iv) puts( )
 Function prototype is found in stdio.h header file
 It is used to print string(set of characters) on screen
 It places newline \n character after printing the string
Syntax: puts(variable_name) ;
Example:
char name[30];
name=”Daisy”
puts(name);
EXAMPLE PROGRAM
#include<stdio.h>
#include<conio.h>
24
void main( )
{
int rno;
char grade,name[30],shname[50];
printf(“Enter name,roll number,grade and school name\n”);
scanf(%s\n%d\n”,name,&rno);
grade=getchar( );
shname=gets( );
printf(“Name=%s\nRoll No=%d”,name,rno);
printf(“\nGrade=”);
putchar(grade);
printf(“\nSchool Name=”);
puts(schname);
getch();
}
OUTPUT
Enter name,roll number,grade and school name
Aishwarya
1101
S
Cambridge School
Name=Aishwarya
Roll No=1101
Grade=S
School Name= Cambridge School

25

You might also like