StudyLover
  • Home
  • Study Zone
  • Profiles
  • Typing Tutor
  • B Tree
  • Contact us
  • Sign in
StudyLover C Programming: Data Types
Download
  1. C Programming
  2. Unit 1: Foundations of Problem Solving & C Language Basics
C Programming: Variables 📦 : C Programming: Basic Data Types 🔢
Unit 1: Foundations of Problem Solving & C Language Basics

C Programming: Data Types

A data type in C is a classification that specifies the type of value a variable can hold. It tells the compiler how much memory to allocate for a variable and defines the set of operations that can be performed on that variable.

Every variable in C must have a data type. This ensures that data is stored and manipulated in a predictable and efficient way. C data types can be broadly classified into three categories:

1.   Basic Data Types

2.   Derived Data Types

3.   User-Defined Data Types


1. Basic (Primary) Data Types 🔢

These are the fundamental data types that are built into the C language. They are used to store simple values like integers, characters, and floating-point numbers.

Data Type

Description

Size (Typical)

Format Specifier

int

Stores whole numbers (e.g., -5, 0, 100).

2 or 4 bytes

%d

char

Stores a single character (e.g., 'a', 'Z', '?').

1 byte

%c

float

Stores decimal numbers with single precision.

4 bytes

%f

double

Stores decimal numbers with double precision.

8 bytes

%lf

void

Represents the absence of a type. Used for functions that do not return a value.

N/A

N/A

 

Type Modifiers: The int and char data types can be modified using keywords like short, long, signed, and unsigned to alter their size or the range of values they can hold. For example, unsigned int can only store non-negative integers.

Example of Basic Data Types

C

#include <stdio.h>

 
int main() {

    int age = 21;

    char grade = 'A';

    float percentage = 85.5f; // 'f' denotes a float literal

    double pi = 3.1415926535;

 
    printf("Age: %d\n", age);

    printf("Grade: %c\n", grade);

    printf("Percentage: %f\n", percentage);

    printf("Value of PI: %lf\n", pi);

 
    return 0;

}


 

2. Derived Data Types

Derived data types are created from the basic data types. They provide ways to group and manage related data. The main derived types are:

·         Arrays: A collection of multiple elements of the same data type, stored in a contiguous block of memory. (e.g., an array of 10 integers).

·         Pointers: Special variables that store the memory address of another variable.

·         Functions: A block of code that performs a specific task and can be called from other parts of the program.

These topics are more advanced and are typically covered in detail after the basics are mastered.


3. User-Defined Data Types 🧑‍🎨

C allows users to define their own data types to suit their specific needs. This is useful for creating more organized and readable code, especially for complex data.

·         Structure (struct): A composite data type that groups together variables of different data types under a single name.

·         Union (union): Similar to a structure, but all its members share the same memory location.

·         Enumeration (enum): A special data type that consists of a set of named integer constants.

Example of a User-Defined Type (struct)

A struct is perfect for grouping related information, like the details of a student.

C

#include <stdio.h>

#include <string.h>

 
// 1. Define a new user-defined data type called 'Student'

struct Student {

    int rollNumber;

    char name[50];

    float gpa;

};

 
int main() {

    // 2. Declare a variable of the new 'Student' type

    struct Student student1;

 
    // 3. Assign values to the members of the variable

    student1.rollNumber = 101;

    strcpy(student1.name, "Rohit Yadav"); // Use strcpy for strings

    student1.gpa = 8.7;

 
    // 4. Access and print the members

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

    printf("Roll Number: %d\n", student1.rollNumber);

    printf("GPA: %f\n", student1.gpa);

 
    return 0;

}

 

C Programming: Basic Data Types 🔢

Basic data types, also known as primary or fundamental data types, are the core building blocks for storing data in C. They are predefined by the language and are used to represent single values like numbers and characters.


int (Integer)

The int data type is used to store whole numbers, both positive and negative, without any decimal part.

·         Purpose: Storing integer values like age, roll numbers, or counts.

·         Size: Typically 4 bytes (32 bits), but this can vary by system.

·         Format Specifier: %d

Example:

C

#include <stdio.h>

 
int main() {

    // Declaring an integer variable

    int year = 2025;

 
    // Declaring another integer for a negative value

    int temperature = -5;

 
    printf("The current year is: %d\n", year);

    printf("The temperature is: %d degrees Celsius\n", temperature);

 
    return 0;

}


 

char (Character)

The char data type is used to store a single character, such as a letter, a digit, or a special symbol. The character must be enclosed in single quotes ('). Internally, characters are stored as integers based on the ASCII character set.

·         Purpose: Storing single characters like a grade, an initial, or a symbol.

·         Size: 1 byte.

·         Format Specifier: %c

Example:

C

#include <stdio.h>

 
int main() {

    char grade = 'A';

    char symbol = '$';

 
    printf("The student's grade is: %c\n", grade);

    printf("The currency symbol is: %c\n", symbol);

    

    // Demonstrating the integer nature of char

    printf("The ASCII value of '%c' is %d\n", grade, grade);

 
    return 0;

}


 

float and double (Floating-Point)

float and double are used to store real numbers (numbers with a decimal point). The main difference is their precision and size.

·         float: For single-precision floating-point numbers. It has about 6-7 digits of precision.

o    Size: 4 bytes.

o    Format Specifier: %f

·         double: For double-precision floating-point numbers. It offers much higher precision (about 15-16 digits) and is generally preferred for real-number calculations.

o    Size: 8 bytes.

o    Format Specifier: %lf

Example:

C

#include <stdio.h>

 
int main() {

    // Use 'f' suffix for float literals

    float price = 499.99f; 

    

    double pi = 3.1415926535;

 
    printf("The price is: %f\n", price);

    printf("The value of PI is: %lf\n", pi);

 
    return 0;

}


 

Type Modifiers

These keywords are used to modify the properties (like size or sign) of the basic integer and character types.

·         short, long: Affect the size of the data type. long int can store larger integers than a plain int.

·         signed, unsigned: Determine if the variable can hold negative values. By default, types are signed. An unsigned int can only store non-negative values (0 and positive), allowing it to hold a larger maximum positive value compared to a signed int of the same size.

Modified Type

Description

unsigned int

Stores only non-negative integers.

long int

Stores a larger range of integers.

long double

Provides even greater precision than double.

unsigned char

Stores character values from 0 to 255.

 


The void Type

The void type is a special-purpose type that has no value. It is primarily used in two scenarios:

1.   Function Return Type: To specify that a function does not return any value.

C

                            void printMessage() {

    printf("This function does not return a value.\n");

}

2.   Generic Pointers: To declare a generic pointer (void *), which is an advanced concept.

 

C Programming: Derived Data Types

Derived data types are complex data types that are built using the basic (primary) data types. They are used to store and manage collections of data or to handle more advanced programming concepts like memory management. The primary derived types in C are Arrays, Pointers, and Functions.


1. Arrays ⛓️

An array is a fixed-size, sequential collection of elements of the same data type. Think of it as a row of numbered containers, where each container holds the same kind of item.

·         Purpose: To store multiple related values under a single variable name.

·         Declaration: data_type array_name[size];

Example

This example stores the marks of 5 subjects in an integer array. Array elements are accessed using an index, which starts from 0.

C

#include <stdio.h>

 
int main() {

    // Declare and initialize an array of 5 integers

    int marks[5] = {85, 90, 78, 92, 88};

 
    printf("Displaying marks of subjects:\n");

 
    // Use a loop to access each element of the array

    // The index goes from 0 to 4

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

        // marks[i] accesses the element at the current index

        printf("Subject %d: %d\n", i + 1, marks[i]);

    }

 
    return 0;

}


 

2. Pointers 👉

A pointer is a special variable that does not store data directly but instead stores the memory address of another variable. It "points to" the location where the data is stored.

·         Purpose: Pointers are essential for dynamic memory allocation, creating complex data structures (like linked lists), and for allowing functions to modify the original variables passed to them.

·         Declaration: data_type *pointer_name;

o    The asterisk (*) indicates that it's a pointer.

Example

This example shows how a pointer stores the address of a variable and how to access the variable's value through the pointer.

C

#include <stdio.h>

 
int main() {

    int age = 25; // A normal integer variable

    

    // A pointer 'ptr' that can store the address of an integer

    int *ptr;

 
    // The '&' operator gets the memory address of 'age'

    ptr = &age;

 
    printf("Value of age (direct access): %d\n", age);

    

    // The '*' operator dereferences the pointer to get the value it points to

    printf("Value of age (via pointer): %d\n", *ptr);

    

    printf("Memory address of age: %p\n", (void *)ptr);

 
    return 0;

}


 

3. Functions ⚙️

A function is a self-contained block of code that performs a specific task. While not a data type in the same way as an array, it's considered derived because its definition involves other data types for its parameters and return value.

·         Purpose: To break down a large program into smaller, reusable, and manageable modules, improving readability and maintainability.

·         Declaration (Prototype): return_type function_name(parameter_type1, parameter_type2);

Example

This example defines a simple function add that takes two integers and returns their sum. The main function calls this add function.

C

#include <stdio.h>

 
// Function prototype (declaration)

int add(int a, int b);

 
// The main function - program execution starts here

int main() {

    int num1 = 10;

    int num2 = 20;

    int sum;

 
    // Calling the 'add' function and storing its return value

    sum = add(num1, num2);

 
    printf("The sum of %d and %d is: %d\n", num1, num2, sum);

 
    return 0;

}

 
// Function definition

int add(int a, int b) {

    // The 'return' keyword sends a value back to the caller

    return a + b;

}

 

C Programming: User-Defined Data Types 🧑‍🎨

User-defined data types allow programmers to create their own data types by grouping existing data types. This is a powerful feature for creating more organized, readable, and meaningful code, especially when dealing with complex data that represents real-world objects.

The main user-defined types in C are struct, union, and enum. The typedef keyword is also used extensively with these types.


1. Structure (struct) 🏗️

A structure is a complex data type that groups together one or more variables of potentially different data types under a single name. Think of it as a template for a record, like a student's ID card which has a name (string), a roll number (integer), and a GPA (float).

·         Purpose: To represent real-world entities and keep related data together.

·         Syntax to Define:

C

struct StructureName {

    dataType member1;

    dataType member2;

    ...

};

Example

This example defines a struct to store information about a car.

C

#include <stdio.h>

#include <string.h>

 
// Define a structure named 'Car'

struct Car {

    char make[20];

    char model[20];

    int year;

};

 
int main() {

    // Declare a variable 'myCar' of type 'struct Car'

    struct Car myCar;

 
    // Access members using the dot (.) operator and assign values

    strcpy(myCar.make, "Toyota");

    strcpy(myCar.model, "Camry");

    myCar.year = 2023;

 
    // Print the members of the structure

    printf("Car Make: %s\n", myCar.make);

    printf("Car Model: %s\n", myCar.model);

    printf("Car Year: %d\n", myCar.year);

 
    return 0;

}


size=2 width="100%" align=center>

2. Union (union) 🔄

A union is a special user-defined data type that allows storing different data types in the same memory location. While a structure allocates enough space for all its members, a union allocates space equal to its largest member. You can only use one member of the union at a time.

·         Purpose: Primarily used for memory optimization in situations where you only need to store one value out of a set of possible types at any given moment.

·         Key Difference from struct: Members of a union share memory.

Example

This example shows how changing one member of the union affects the others because they all share the same memory space.

C

#include <stdio.h>

 
union Data {

    int i;

    float f;

};

 
int main() {

    union Data data;

 
    data.i = 10;

    printf("Value of i: %d\n", data.i); // i is active, so this is correct

 
    data.f = 220.5;

    printf("Value of f: %f\n", data.f); // f is now active

 
    // The value of 'i' is now corrupted because 'f' is using the memory

    printf("Value of i after changing f: %d\n", data.i); 

 
    return 0;

}


size=2 width="100%" align=center>

3. Enumeration (enum) 📋

An enumeration is a special data type that consists of a set of named integer constants. It makes the code more readable and less prone to errors by using descriptive names instead of "magic numbers."

·         Purpose: To assign meaningful names to a set of integral constants. By default, the first name is 0, the second is 1, and so on.

Example

This example uses an enum to represent the days of the week, making the switch statement very clear.

C

#include <stdio.h>

 
// Define an enumeration for days of the week

enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

 
int main() {

    enum Day today = Wednesday;

 
    switch (today) {

        case Sunday:

            printf("It's Sunday.\n");

            break;

        case Monday:

            printf("It's Monday.\n");

            break;

        // ... other days

        default:

            printf("It's some other day.\n");

    }

    

    // Enums are integers internally

    printf("Wednesday is day number: %d\n", today); // Will print 3

 
    return 0;

}


size=2 width="100%" align=center>

typedef Keyword

The typedef keyword is used to create an alias or a new, simpler name for an existing data type. It doesn't create a new type but just provides an alternative name.

·         Purpose: To simplify complex type names and improve code readability, especially with structures.

Example

This example uses typedef to create a simpler alias Car for struct Car, so we don't have to write struct every time.

C

#include <stdio.h>

#include <string.h>

 
// Use typedef to create an alias 'Car' for 'struct Car'

typedef struct Car {

    char model[20];

    int year;

} Car; // The new name 'Car' is now an alias

 
int main() {

    // We can now use 'Car' directly instead of 'struct Car'

    Car myCar; 

 
    strcpy(myCar.model, "Civic");

    myCar.year = 2024;

 
    printf("Model: %s, Year: %d\n", myCar.model, myCar.year);

 
    return 0;

}

 

Advanced Concepts in C Data Types

Understanding C data types at an advanced level involves looking at how they are represented in memory, how the compiler optimizes them, and the rules that govern their interactions in expressions.


1. Memory Representation of Data Types 🧠

How a value is physically stored in memory is determined by its data type.

·         Integral Types (int, char): These are typically stored using the Two's Complement binary representation. This system is highly efficient for hardware to perform arithmetic on and allows both positive and negative numbers to be represented without a separate sign bit. For a negative number, the bits of its positive counterpart are inverted, and one is added.

·         Floating-Point Types (float, double): These are stored using the IEEE 754 standard. This format breaks a number into three parts:

1.   Sign Bit: 1 bit indicating if the number is positive (0) or negative (1).

2.   Exponent: Stores the "order of magnitude" of the number, allowing for a very large or very small range.

3.   Mantissa (or Fraction): Stores the actual significant digits of the number.


2. Data Alignment and Structure Padding 📐

CPUs are most efficient when they access data from memory addresses that are a multiple of the data's size (e.g., a 4-byte int should be at an address divisible by 4). This is called data alignment.

To enforce this, the C compiler often inserts unused bytes into structures to ensure each member is correctly aligned. This process is called structure padding. This is why the size of a struct can be greater than the sum of the sizes of its members.

Example

C

#include <stdio.h>

 
struct Example {

    char a;    // 1 byte

    // 3 bytes of padding are added here by the compiler

    int b;     // 4 bytes

    char c;    // 1 byte

    // 3 bytes of padding are added here for overall alignment

};

 
int main() {

    printf("Size of char: %zu\n", sizeof(char));

    printf("Size of int: %zu\n", sizeof(int));

    

    // The sum of member sizes is 1 + 4 + 1 = 6 bytes.

    // However, due to padding, the actual size will be larger.

    printf("Size of struct Example: %zu\n", sizeof(struct Example)); // Typically prints 12

 
    return 0;

}

Explanation: The compiler adds 3 bytes of padding after char a so that int b can start on a 4-byte boundary. It then adds 3 more bytes at the end so that the total size of the structure is a multiple of its largest member's alignment (which is 4).


3. Advanced Type Qualifiers ✨

·         const Pointers: The const keyword can be used with pointers in three distinct ways:

1.   Pointer to a const value: The data pointed to cannot be changed, but the pointer can be moved.

C

const int *p; // or int const *p;

2.   const Pointer: The pointer itself cannot be changed to point to something else, but the data it points to can be modified.

C

int * const p;

3.   const Pointer to a const value: Neither the pointer nor the data it points to can be changed.

C

const int * const p;

·         volatile: This qualifier tells the compiler that a variable's value can be changed at any time by something outside the program's control (e.g., a hardware device, another thread). It forces the compiler to reload the variable's value from memory every time it's accessed and prevents optimizations that might assume the value is unchanged.

C

// Used for a memory-mapped hardware register

volatile unsigned int *hardware_register;

·         restrict (C99): This is a hint to the compiler that for the lifetime of the pointer, only that pointer or values derived directly from it will be used to access the object it points to. This allows the compiler to perform more aggressive optimizations, as it doesn't need to worry about other pointers aliasing the same memory.

C

// Tells the compiler that ptr1 and ptr2 do not overlap

void add_arrays(int *restrict ptr1, int *restrict ptr2, int size);


 

4. Type Conversions and Promotion Rules 📈

·         Implicit Conversion (Promotion): When different data types are used in an expression, C automatically converts them to a common type based on a set of rules.

o    Integer Promotion: Types smaller than int (like char and short) are automatically promoted to int or unsigned int before any operation.

o    Usual Arithmetic Conversions: In an operation with mixed types (e.g., int and double), the "lower" type is promoted to the "higher" type before the operation is performed. The hierarchy is generally long double > double > float > unsigned long long > long long > ... > int.

·         Explicit Conversion (Casting): You can force a conversion using the cast operator (type). This can be risky and can lead to loss of information.

Example

C

#include <stdio.h>

 
int main() {

    int i = 10;

    float f = 5.5;

    double d = 20.2;

 
    // Implicit conversion: 'i' is promoted to float before addition

    float result1 = i + f; 

    printf("Implicit (int + float): %f\n", result1);

 
    // Explicit conversion (casting): 'd' is truncated to an integer

    int result2 = (int)d; 

    printf("Explicit (double to int): %d\n", result2); // Fractional part is lost

 
    return 0;

}

C Programming: Variables 📦 C Programming: Basic Data Types 🔢
Our Products & Services
  • Home
Connect with us
  • Contact us
  • +91 82955 87844
  • Rk6yadav@gmail.com

StudyLover - About us

The Best knowledge for Best people.

Copyright © StudyLover
Powered by Odoo - Create a free website