QUESTION 01
What is a structure?
2 marksAnswer
A structure groups named members, possibly of different types, into one user-defined aggregate type. Each object contains its own member objects.

AR25 · I Year II Semester · Unit I — Structure and Union Types
QUESTION 01
A structure groups named members, possibly of different types, into one user-defined aggregate type. Each object contains its own member objects.
QUESTION 02
A structure represents related data as one record, such as a student’s roll number and marks.
struct Student {
int roll;
double marks;
};
struct Student s = {101, 87.5};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.
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.
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.
/* 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;
}The example uses values in the code.
Roll = 101, marks = 87.5QUESTION 03
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
Structure input and output operate on suitable members. A structure is not printed meaningfully by passing the whole object to an arbitrary format.
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.
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.
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.
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.
/* 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;
}101 87.5Roll = 101, marks = 87.5QUESTION 05
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
An array of structures stores several records of the same kind in contiguous array storage.
struct Student { int roll; int marks; };
struct Student students[3] = {{101, 70}, {102, 85}, {103, 80}};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.
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.
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.
/* 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;
}The example uses values in the code.
Best roll = 102, marks = 85QUESTION 07
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
Complex records combine simpler members, arrays, nested structures or pointers to represent more detailed information.
struct Date { int day, month, year; };
struct Student { int roll; struct Date joined; char name[40]; };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.
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.
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.
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
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
A function can receive a structure value for reading or a pointer for access to the caller’s object.
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.
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.
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.
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.
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.
/* 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;
}The example uses values in the code.
Marks = 80QUESTION 11
Yes. Its declared return type can be a complete structure type, and return can supply a compatible structure value.
QUESTION 12
Returning a structure lets a function produce several related result members as one value.
struct Pair { int minimum, maximum; };
struct Pair extremes(int a, int b);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.
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.
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.
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.
/* 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;
}The example uses values in the code.
Minimum = 4, maximum = 9QUESTION 13
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
Self-referential structures connect separate objects into lists, trees and other linked arrangements.
struct Node {
int data;
struct Node *next;
};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.
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.
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.
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.
QUESTION 15
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
Bit-fields describe small-width integer members, often used for compact flags or bounded state values.
struct Flags {
unsigned int ready : 1;
unsigned int mode : 2;
};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.
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.
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.
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.
/* 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;
}The example uses values in the code.
Ready = 1, mode = 3QUESTION 17
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
A union offers alternative representations within one shared storage area.
union Value { int count; double price; };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.
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.
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.
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.
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.
/* 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;
}The example uses values in the code.
Count = 5
Price = 12.5QUESTION 19
A structure has separate member storage so all members can hold values together. Union members overlap and represent alternatives.
QUESTION 20
Structures model a group of values needed together. Unions model alternative values sharing storage.
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.
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.
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.
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.
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.
| Feature | Structure | Union |
|---|---|---|
| Member storage | Separate | Overlapping |
| Typical values | Needed together | Alternative payloads |
| Size | Members plus permitted padding | Enough for alternatives and alignment |
| Use | Student record | Tagged alternative value |
QUESTION 21
It introduces another name for an existing type. It does not allocate an object or create a distinct incompatible type by itself.
QUESTION 22
typedef gives a type a convenient alias that can make declarations easier to read.
typedef unsigned long Count;
typedef struct { int x, y; } Point;
Point p = {2, 3};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.
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.
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
An enum declares named integer constants for a related group, such as enum State { IDLE, RUNNING, DONE };.
QUESTION 24
Enumeration constants give meaningful names to related integer choices or states.
enum State { IDLE, RUNNING = 5, DONE };
enum State state = RUNNING;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.
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.
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.
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.
/* 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;
}The example uses values in the code.
Running