Skip to study material
CodeBhavya

Data Structures

AR25 · I Year II Semester · Unit I — Structure and Union Types

← Question index

QUESTION 01

What is a structure?

2 marks

Answer

A structure groups named members, possibly of different types, into one user-defined aggregate type. Each object contains its own member objects.

QUESTION 02

Explain user-defined structure types, declaration and member access.

5 marks

Answer in brief

A structure represents related data as one record, such as a student’s roll number and marks.

Declaration

struct Student {
    int roll;
    double marks;
};
struct Student s = {101, 87.5};

Members and access

The tag Student names the structure type. The definition lists an int member roll and a double member marks. s is an object of that type. Use s.roll and s.marks to select its members. A member assignment such as s.marks = 90.0 changes only that member of s.

Why structures are useful

  1. Keep related values together instead of maintaining unrelated variables.
  2. Pass or return a complete record in a function interface.
  3. Create arrays of records for students, products or employees.
  4. Combine structures with pointers to build linked data structures.

Initialisation and storage

The braces supply initial values in member order. A designated initialiser, such as {.marks = 87.5, .roll = 101}, can name members explicitly. Storage may include padding for alignment, so sizeof(struct Student) need not equal the sum of the written member sizes. Do not assume a fixed byte layout across computers.

Complexity

Accessing a fixed member takes O(1) work. Processing n records generally requires O(n) traversal work. Structure definition alone does not execute input or output; the program must read and display members explicitly.

Diagram or flowchart

CodeBhavya illustration of structure
Explain user-defined structure types, declaration and member access. · Download diagram

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Student { int roll; double marks; };

int main(void)
{
    struct Student s = {101, 87.5};
    printf("Roll = %d, marks = %.1f\n", s.roll, s.marks);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Roll = 101, marks = 87.5

QUESTION 03

How is a structure member read with scanf?

2 marks

Answer

Pass the address of the selected member with a matching format, such as scanf("%d", &s.roll). Check the conversion result before use.

QUESTION 04

Explain initialisation and input/output of structure members.

5 marks

Answer in brief

Structure input and output operate on suitable members. A structure is not printed meaningfully by passing the whole object to an arbitrary format.

Algorithm

  1. Declare the structure type and an object.
  2. Read each member using its proper type and valid bounds.
  3. Reject failed input before relying on the member values.
  4. Display selected members with matching output formats.

Example

The sample reads a roll number and a double mark into one student record. %d matches int. scanf uses %lf with double *, while printf uses %f for the displayed double. The & operator supplies the destination address for each input conversion.

Initialisation

struct Student s = {0}; gives the first member zero and zero-initialises remaining members according to their types. This is different from an ordinary automatic object with no initialiser. Input validation is still necessary even when a safe starting value exists.

Text members

A character-array member needs enough capacity for its text and terminator. Whole-line input using fgets is suitable for names containing spaces. Mixing token-based numeric reads and line input needs deliberate handling of any remaining newline. Avoid unbounded %s or gets.

Correctness and cost

The example accepts only marks between 0 and 100 and a bounded positive roll number. These are sample constraints, not an institutional grading policy. Reading a fixed number of scalar members takes O(1) element operations; reading a variable-length text member also depends on its length.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Student { int roll; double marks; };

int main(void)
{
    struct Student s = {0};
    if (scanf("%d%lf", &s.roll, &s.marks) != 2 || s.roll < 1 || s.roll > 10000 || !(s.marks >= 0 && s.marks <= 100)) {
        puts("Invalid input"); return 1;
    }
    printf("Roll = %d, marks = %.1f\n", s.roll, s.marks);
    return 0;
}

Sample input and output

Input

101 87.5

Output

Roll = 101, marks = 87.5

QUESTION 05

What is an array of structures?

2 marks

Answer

It is an array whose elements share one structure type. a[i] selects a record and a[i].member selects one member of that record.

QUESTION 06

Explain arrays of structures with a record-processing example.

5 marks

Answer in brief

An array of structures stores several records of the same kind in contiguous array storage.

Declaration

struct Student { int roll; int marks; };
struct Student students[3] = {{101, 70}, {102, 85}, {103, 80}};

Working

students[1] is the second complete record. students[1].marks selects its mark, 85. A loop from index 0 through 2 can process every record. Each structure element contains its own members; changing one record’s mark does not change another record.

Finding the best record

  1. Require a non-empty active list.
  2. Start best at index 0.
  3. Compare each later record’s marks with students[best].marks.
  4. Update best when a larger mark is found, then display the chosen record.

Example trace

For marks 70, 85 and 80, best starts at 0, changes to 1 on seeing 85 and remains 1 for 80. The chosen roll is 102. With a strict greater-than comparison, an equal later mark does not replace the first maximum.

Complexity and bounds

A single member access is O(1). Finding the largest mark scans n records and takes O(n) time with O(1) auxiliary space. The input records themselves require O(n) storage. Keep the active count within the actual array capacity; a structure member does not remove normal C array-bound rules.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Student { int roll, marks; };

int main(void)
{
    struct Student s[3] = {{101, 70}, {102, 85}, {103, 80}};
    int best = 0;
    for (int i = 1; i < 3; ++i) { if (s[i].marks > s[best].marks) { best = i; } }
    printf("Best roll = %d, marks = %d\n", s[best].roll, s[best].marks);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Best roll = 102, marks = 85

QUESTION 07

What is a nested structure?

2 marks

Answer

A structure containing another structure as a member is nested. A member such as s.date.day is reached through successive member selections.

QUESTION 08

Explain nested structures and structures containing arrays or pointers.

5 marks

Answer in brief

Complex records combine simpler members, arrays, nested structures or pointers to represent more detailed information.

Nested example

struct Date { int day, month, year; };
struct Student { int roll; struct Date joined; char name[40]; };

Access

s.joined.day selects a day inside the nested date. s.name is an array within the student object and can hold at most 39 non-null text bytes plus its terminator. The nested object and the array are parts of each record, rather than separately allocated targets.

Pointer members

A pointer member can identify separate storage, but it does not automatically allocate or own that storage. If a structure is copied, the pointer value is copied. Its target is not duplicated automatically. An ownership rule must say which operation creates, shares or frees that target.

Shallow-copy example

If two records are copied and both contain the same pointer address, both can reach the same target. Freeing the target through one record leaves the other pointer unusable for access. A deep copy is a deliberate process that allocates and copies separate target objects; ordinary structure assignment does not do this.

Design and complexity

Choose nested objects for values that belong directly to a record and pointers for relationships or separately managed storage. Direct member selection is O(1), while processing a variable-length member or duplicating its target depends on that data’s size. Write clear lifetime and capacity rules.

QUESTION 09

How can a function change the caller’s structure?

2 marks

Answer

Pass a pointer to the caller’s structure and assign through it. Passing a structure by value instead gives the function its own parameter copy.

QUESTION 10

Explain structures as input and output function parameters.

5 marks

Answer in brief

A function can receive a structure value for reading or a pointer for access to the caller’s object.

Value parameter

void display(struct Student s) receives a structure value. Changes to s.roll or s.marks inside that function affect only the parameter object. This provides a simple interface when a record should not be replaced by the function.

Pointer parameter

void update(struct Student *p) can assign p->marks. The arrow operator accesses a member of the structure identified by p; p->marks means (*p).marks. The caller passes &student. A reading function can take const struct Student *p to prevent member modification through that access.

Example trace

The complete example starts with marks 70. update(&s, 80) receives the address and assigns p->marks = 80. main then displays 80, because the original object was modified. Passing a pointer is still C pass by value: the copied value is an address.

Validity and output

A pointer must identify a live, suitable structure object. Checking against NULL does not prove every non-null address is valid. Output can be a returned scalar, a returned structure or an object changed through a pointer, depending on the interface.

Complexity

For this fixed-size record, the update takes O(1) work and space. For larger records, value passing can involve copying the record representation; using a pointer avoids explicitly requesting a full record copy at the source interface. Pointer members still need separate ownership rules.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Student { int roll, marks; };
void update(struct Student *p, int marks)
{
    if (p != NULL) { p->marks = marks; }
}

int main(void)
{
    struct Student s = {101, 70};
    update(&s, 80);
    printf("Marks = %d\n", s.marks);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Marks = 80

QUESTION 11

Can a C function return a structure?

2 marks

Answer

Yes. Its declared return type can be a complete structure type, and return can supply a compatible structure value.

QUESTION 12

Explain functions that return structure values.

5 marks

Answer in brief

Returning a structure lets a function produce several related result members as one value.

Example interface

struct Pair { int minimum, maximum; };
struct Pair extremes(int a, int b);

Working

The function creates a local result object, fills its two members and returns its value. The caller can initialise or assign a compatible structure object from that returned value. The caller does not need to receive a pointer to the function’s ordinary local object.

Example trace

extremes(9, 4) sets minimum to 4 and maximum to 9. The returned Pair initialises result in main. Reading result.minimum and result.maximum displays both outputs. The local function object can finish its lifetime because its value has been returned.

Value versus address

Returning a local structure value is valid. Returning the address of an ordinary automatic local structure is different and unsafe for later access, because that object’s lifetime ends. If the returned record contains pointers, their targets must separately remain valid; value return does not extend those targets’ lifetimes.

Advantages and cost

A result record gives meaningful names to related outputs and avoids several unrelated output parameters. It is useful for a minimum/maximum pair, a coordinate or a parsed record. For the fixed two-int result, the example uses O(1) work and extra space. Larger record copying and pointer-target processing depend on their sizes and the implementation.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Pair { int minimum, maximum; };
struct Pair extremes(int a, int b)
{
    struct Pair result;
    result.minimum = a < b ? a : b;
    result.maximum = a > b ? a : b;
    return result;
}

int main(void)
{
    struct Pair result = extremes(9, 4);
    printf("Minimum = %d, maximum = %d\n", result.minimum, result.maximum);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Minimum = 4, maximum = 9

QUESTION 13

What is a self-referential structure?

2 marks

Answer

It contains a pointer to its own structure type, such as struct Node *next. It cannot contain an ordinary direct member of its own incomplete type.

QUESTION 14

Explain self-referential structures and their role in linked lists.

5 marks

Answer in brief

Self-referential structures connect separate objects into lists, trees and other linked arrangements.

Node definition

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

Why a pointer is used

The structure cannot contain a complete instance of itself directly: that would require another instance inside it, without a finite completed layout. A pointer has a usable pointer type while the node definition is being completed, so next can identify another node.

Linking example

Two separate Node objects can hold 10 and 20. Set the first node’s next to the address of the second and set the second node’s next to NULL. Starting with the first node, following next reaches the second, then detects the null link at the end.

Lifetime and ownership

A node pointer does not create its target. Nodes may have automatic, static or allocated storage with different lifetimes. In a dynamic list, allocate each needed node, check the result and free it when removed. Never retain a link to an object whose lifetime has ended.

Complexity

Reading the current node’s data or next member is O(1). Following links to visit n nodes takes O(n) time. A single next link does not provide constant-time indexed access to an arbitrary position. This type is the foundation for the singly linked-list operations in Unit III.

Diagram or flowchart

CodeBhavya illustration of nodes
Explain self-referential structures and their role in linked lists. · Download diagram

QUESTION 15

What is a bit-field?

2 marks

Answer

It is a structure or union member declared with a bit width, such as unsigned int ready : 1;. It can represent small integer state fields.

QUESTION 16

Explain structure bit-fields, uses and limitations.

5 marks

Answer in brief

Bit-fields describe small-width integer members, often used for compact flags or bounded state values.

Declaration

struct Flags {
    unsigned int ready : 1;
    unsigned int mode : 2;
};

Meaning

ready can hold 0 or 1. mode can hold 0 through 3 for this unsigned two-bit field. Access uses the normal dot or arrow member operators. Assign only values suitable for the field’s width and intended meaning.

Uses

  1. Represent several yes/no flags in one record.
  2. Store small status values when the implementation’s layout is acceptable.
  3. Give meaningful field names rather than repeatedly writing manual bit masks.

Limitations

The packing order and allocation-unit details are implementation-dependent. Do not use a bit-field structure as a portable network packet or file format without an explicit external encoding. A bit-field is not an addressable ordinary object: its address cannot be taken with &. sizeof cannot be applied to a bit-field expression.

Type and layout rules

For introductory portable declarations, use unsigned int, signed int or _Bool as appropriate. Plain int field signedness is implementation-defined. A zero-width unnamed field has a layout purpose and is not a normal named value. Do not promise a particular total byte saving: padding and packing rules vary.

Example and complexity

The program assigns ready = 1 and mode = 3, then displays their promoted values. Each fixed field operation is O(1) in the usual model. Bit-fields improve a representation only when their restrictions fit the task.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
struct Flags { unsigned int ready : 1; unsigned int mode : 2; };

int main(void)
{
    struct Flags f = {0};
    f.ready = 1; f.mode = 3;
    printf("Ready = %u, mode = %u\n", (unsigned)f.ready, (unsigned)f.mode);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Ready = 1, mode = 3

QUESTION 17

What is a union?

2 marks

Answer

A union is a type whose members share overlapping storage. It is normally used to hold one selected member value at a time.

QUESTION 18

Explain union types and contrast their storage with structures.

5 marks

Answer in brief

A union offers alternative representations within one shared storage area.

Declaration

union Value { int count; double price; };

Storage

The union must be large enough and suitably aligned for its members, possibly with padding. Unlike a structure, it does not reserve independent simultaneous storage for every member. Do not assume its size is exactly the largest member size without considering layout requirements.

Example

Assign v.count = 5 and use v.count. Later assign v.price = 12.5 and use v.price. The later write replaces the shared representation; count and price should not be treated as two independent values retained together.

Choosing the current member

A tagged union pairs a discriminator, often an enum, with a union. The tag records whether the current intended value is a count, price or another alternative. Every update must keep the tag and stored member consistent. The tag is separate data; C does not maintain it automatically.

Precaution

For clear introductory code, read the member corresponding to the stored alternative. Reading a different member reinterprets stored representation and can have implementation-dependent results or invalid representations. It is not a portable general-purpose numeric conversion; use a normal value conversion when converting int to double.

Complexity

Selecting a known member is O(1). A union can avoid allocating separate space for alternatives that are never needed simultaneously. The memory benefit depends on the actual member types and alignment.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
union Value { int count; double price; };

int main(void)
{
    union Value v;
    v.count = 5; printf("Count = %d\n", v.count);
    v.price = 12.5; printf("Price = %.1f\n", v.price);
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Count = 5
Price = 12.5

QUESTION 19

State one storage difference between a structure and a union.

2 marks

Answer

A structure has separate member storage so all members can hold values together. Union members overlap and represent alternatives.

QUESTION 20

Compare structure and union types with suitable uses.

5 marks

Answer in brief

Structures model a group of values needed together. Unions model alternative values sharing storage.

Structure

A Student record can need roll, name and marks at the same time. Its members occupy distinct parts of the record, although padding may occur between or after them. Assigning one ordinary member does not overwrite an unrelated member.

Union

A Value union may hold a count or price alternative. The members overlap, so storing the price changes the shared representation that was used for count. Use a suitable tag to remember which alternative the program intends to read.

Shared features

Both are user-defined types with named members accessed using . on an object or -> through a suitable pointer. Both can be nested in other aggregates and used in function interfaces. Neither is an automatic mechanism for text input validation, target allocation or pointer ownership.

Size comparison

The structure size includes the storage needed for all members plus permitted padding. The union size is enough for its alternatives and alignment. Do not write a universal formula that ignores padding or assumes identical numeric sizes on every system.

Choosing a representation

Use a structure for a complete employee record. Use a tagged union for a token whose payload is one of several kinds. A structure containing an enum tag and a union payload combines both ideas. Fixed member access takes O(1); processing a variable-length pointed-to payload has its own cost.

Reference table

↔ Scroll horizontally on a small screen
Structure and union
FeatureStructureUnion
Member storageSeparateOverlapping
Typical valuesNeeded togetherAlternative payloads
SizeMembers plus permitted paddingEnough for alternatives and alignment
UseStudent recordTagged alternative value

QUESTION 21

What does typedef do?

2 marks

Answer

It introduces another name for an existing type. It does not allocate an object or create a distinct incompatible type by itself.

QUESTION 22

Explain typedef and its use with structures and pointers.

5 marks

Answer in brief

typedef gives a type a convenient alias that can make declarations easier to read.

Examples

typedef unsigned long Count;
typedef struct { int x, y; } Point;
Point p = {2, 3};

Working

Count is an alias for unsigned long. Point names the stated structure type, so Point p declares an object without repeating struct before the type name. The typedef declaration itself is not the object p and does not store a coordinate.

Advantages

  1. Give a meaningful role name to a suitable underlying type.
  2. Simplify repeated structure declarations.
  3. Centralise a representation choice when interfaces consistently use the alias.
  4. Make complex function-pointer declarations easier to manage.

Pointer aliases

typedef int *IntPointer; makes both a and b pointers in IntPointer a, b;. This differs from int *a, b;, where only a is a pointer. However, hiding a pointer can also obscure const behaviour: const IntPointer qualifies the pointer object, not the pointed-to int. Keep aliases understandable.

Important distinction

typedef is not a preprocessor #define. It participates in C’s declaration and type rules rather than merely replacing tokens. It does not automatically change a data structure’s runtime performance or allocate new storage. A type alias can improve readability, but the underlying type’s size, range and operations still apply.

QUESTION 23

What is an enumeration?

2 marks

Answer

An enum declares named integer constants for a related group, such as enum State { IDLE, RUNNING, DONE };.

QUESTION 24

Explain enumeration types and their use as named states.

5 marks

Answer in brief

Enumeration constants give meaningful names to related integer choices or states.

Declaration

enum State { IDLE, RUNNING = 5, DONE };
enum State state = RUNNING;

Values

The first constant without an explicit value starts at 0. A later unspecified constant is one more than the preceding value. In this example IDLE is 0, RUNNING is 5 and DONE is 6. Explicit values can represent a chosen external convention when that convention is suitable.

Uses

An enum can name menu choices, a machine state, an operation kind or the tag of a union. The program can use these names in if or switch rather than unexplained numbers. The example’s switch recognises RUNNING and displays a matching message.

Enum versus strings

The constant RUNNING is not the text "RUNNING". Printing its name requires a mapping, such as a switch. In the C11 model used here, enumeration constants have type int. The size of an enum object is not guaranteed to be one byte or identical on every implementation.

Important points

Choose distinct values when distinct cases are required, especially in switch labels. An enum does not automatically check every incoming integer against a permitted state list. Validate external input before treating it as a meaningful state. Using a named state comparison or switch branch adds only fixed work in this small example; the chosen action has its own cost.

Complete C example

main.c

Download main.c
/* CodeBhavya | Data Structures AR25 | Learning example */
#include <stdio.h>
enum State { IDLE, RUNNING = 5, DONE };

int main(void)
{
    enum State state = RUNNING;
    switch (state) {
    case IDLE: puts("Idle"); break;
    case RUNNING: puts("Running"); break;
    case DONE: puts("Done"); break;
    default: puts("Unknown"); break;
    }
    return 0;
}

Sample input and output

The example uses values in the code.

Output

Running