# Data types

Alright, let’s dive into **data types** in C. These are essential because they define what kind of data a variable can hold and how much memory it takes up. Let's break them down!

#### **1. Basic Data Types in C**

C provides several standard data types:

| Data Type | Description                       | Size (bytes) | Range                           |
| --------- | --------------------------------- | ------------ | ------------------------------- |
| `int`     | Integer numbers                   | 4            | -2,147,483,648 to 2,147,483,647 |
| `float`   | Single-precision floating point   | 4            | ±3.4E-38 to ±3.4E+38            |
| `double`  | Double-precision floating point   | 8            | ±1.7E-308 to ±1.7E+308          |
| `char`    | Single character                  | 1            | 0 to 255 (ASCII values)         |
| `void`    | Represents the absence of a value | 0            | N/A                             |

#### **2. Integer Types**

Integers (`int`) are the most commonly used data type in C. They store whole numbers, both positive and negative. If you need more specific integer types, you can use **short**, **long**, and **unsigned** variations:

* **`short int`**: Takes less memory but has a smaller range.
* **`long int`**: Takes more memory and has a bigger range.
* **`unsigned int`**: Can only store positive numbers but gives you more range in the positive side.

**Example:**

```c
short int a = 10;   // short integer
long int b = 123456789;  // long integer
unsigned int c = 250;   // unsigned integer
```

#### **3. Floating-Point Types**

Floating-point types are used to represent real numbers (numbers with fractions/decimal points).

* **`float`**: Single-precision (7 decimal places).
* **`double`**: Double-precision (15-16 decimal places). It’s more precise but takes up more memory.

**Example:**

```c
float height = 5.9;  // float for decimal values
double pi = 3.14159265359;  // double for higher precision
```

#### **4. Character Type (`char`)**

The `char` data type stores single characters. In reality, it stores an **ASCII** value (a numeric code representing characters). A character can be enclosed in single quotes (`'A'`, `'5'`, `'?'`).

**Example:**

```c
char grade = 'A';  // stores the character 'A'
char symbol = '@';  // stores the character '@'
```

You can also perform **arithmetic operations** with `char` because it’s stored as a number in memory (ASCII value).

**Example:**

```c
char letter = 'A';  // ASCII value of 'A' is 65
letter = letter + 1;  // Now letter is 'B' (ASCII value 66)
```

#### **5. Void Type (`void`)**

The `void` type is used to indicate **no value** or **empty**. You’ll mostly see `void` in:

* **Function return types**: It tells the function not to return any value.
* **Function parameters**: Tells the function it doesn’t take any arguments.

**Example:**

```c
void greet() {
    printf("Hello, world!\n");
}
```

This function does not return any value (`void` return type).

#### **6. Modifiers for Data Types**

You can modify data types in C to adjust their size and range. Some common modifiers are:

* **`signed`**: Default for integers, allows storing negative and positive numbers.
* **`unsigned`**: For non-negative numbers only, gives a larger range of positive numbers.
* **`short`**: Uses less memory but has a smaller range.
* **`long`**: Uses more memory and allows for a larger range.

**Example:**

```c
unsigned int count = 100;  // count can't be negative
long double precision_value = 3.1415926535;
```

#### **7. Size of Data Types**

The size of each data type depends on the system architecture (32-bit or 64-bit). You can use the `sizeof()` operator to find out the size of any data type.

**Example:**

```c
int main() {
    printf("Size of int: %lu bytes\n", sizeof(int));
    printf("Size of float: %lu bytes\n", sizeof(float));
    printf("Size of double: %lu bytes\n", sizeof(double));
    return 0;
}
```

***

#### **Data Type Cheat Sheet**

Here’s a quick summary of common data types in C:

| **Data Type**                 | **Size (bytes)**       | **Format Specifier** | **When to Use**                                                      |
| ----------------------------- | ---------------------- | -------------------- | -------------------------------------------------------------------- |
| `char`                        | 1                      | `%c`                 | Store single characters (1 byte).                                    |
| `signed char`                 | 1                      | `%hhi`               | Same as `char`, but stores values from -128 to 127.                  |
| `unsigned char`               | 1                      | `%hhu`               | Stores positive small integers (0 to 255).                           |
| `short` / `short int`         | 2                      | `%hd`                | For small integer values (-32,768 to 32,767).                        |
| `unsigned short`              | 2                      | `%hu`                | For small non-negative integers (0 to 65,535).                       |
| `int`                         | 4                      | `%d`, `%i`           | General-purpose integer (-2,147,483,648 to 2,147,483,647).           |
| `unsigned int`                | 4                      | `%u`                 | For non-negative integers (0 to 4,294,967,295).                      |
| `long` / `long int`           | 4 (32-bit), 8 (64-bit) | `%ld`                | Larger integers, used when a broader range than `int` is needed.     |
| `unsigned long`               | 4 (32-bit), 8 (64-bit) | `%lu`                | Non-negative large integers, for bigger numbers than `int`.          |
| `long long` / `long long int` | 8                      | `%lld`               | For extremely large integers (-2^63 to 2^63-1).                      |
| `unsigned long long`          | 8                      | `%llu`               | For very large non-negative integers (0 to 2^64-1).                  |
| `float`                       | 4                      | `%f`                 | Single-precision floating-point (decimal) numbers.                   |
| `double`                      | 8                      | `%lf`                | Double-precision floating-point numbers, more accuracy than `float`. |
| `long double`                 | 12 (or 16)             | `%Lf`                | Extended precision floating-point, for higher precision.             |
| `_Bool` / `bool`              | 1                      | `%d`                 | For boolean values (`true`/`false`), included in `<stdbool.h>`.      |
| `void`                        | 0                      | N/A                  | For functions that don't return a value or generic pointers.         |
| `size_t`                      | Platform-dependent     | `%zu`                | Used for representing sizes, e.g., array indexing.                   |
| `ptrdiff_t`                   | Platform-dependent     | `%td`                | Represents difference between two pointers.                          |
| `wchar_t`                     | 2 or 4                 | `%lc`                | For wide characters, used in internationalization (Unicode).         |
| `intptr_t`                    | Platform-dependent     | `%td`                | Integer type capable of holding a pointer.                           |
| `uintptr_t`                   | Platform-dependent     | `%tu`                | Unsigned integer type for holding a pointer.                         |

#### Special Data Types:

| **Data Type** | **Size (bytes)**                       | **Format Specifier** | **When to Use**                                                       |
| ------------- | -------------------------------------- | -------------------- | --------------------------------------------------------------------- |
| `enum`        | Varies (depends on compiler)           | `%d`                 | To define a set of named integral constants (e.g., days of the week). |
| `union`       | Varies (depends on the largest member) | N/A                  | When you need to store different types in the same memory space.      |
| `struct`      | Varies                                 | N/A                  | To group different data types together.                               |
| `typedef`     | N/A                                    | N/A                  | Used to give a new name (alias) to an existing type.                  |

#### Additional Notes:

* The size of data types like `int`, `long`, and `float` can vary depending on the system's architecture (32-bit vs 64-bit).
* Format specifiers are used for I/O functions like `printf` and `scanf` to identify the data type being processed.
* `typedef` allows you to create your own type names, but it doesn't affect the size or structure of the underlying type.

That should be enough for now!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cs.d19.in/c-programming/basics/data-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
