Tipos de datos
El tipo de datos en términos simples nos da información sobre el tipo de datos.
Ejemplo, entero, carácter, etc.
Los tipos de datos en lenguaje C son declaraciones para las variables . Los tipos de datos se clasifican como:
Tipos de datos primitivos o incorporados
Algunos de los ejemplos de tipos de datos primitivos son los siguientes
La variable llamada ch se refiere a la dirección de memoria 100, ha ocupado 1 byte de memoria, que contiene el valor del tipo de datos char ‘A’.
num es de tipo entero y se refiere a la dirección de memoria 200, ha ocupado 4 bytes de memoria y tiene el valor 123456.
marcas es de tipo doble, se refiere a la ubicación de memoria 300, ha ocupado 8 bytes de memoria y tiene el valor 97.123456.
Nota: estas direcciones (100, 200 y 300) son solo para fines de comprensión, las direcciones reales son números hexadecimales grandes.
arreglos
Una array es una variable que puede almacenar múltiples valores del mismo tipo de datos. Array es un segmento de memoria contiguo.
Ejemplo:
Si desea almacenar 100 enteros, puede usar una array en lugar de usar 100 variables enteras diferentes.
Sintaxis para la declaración de array:
data_type array_name[array_size];
Cantidad de espacio asignado = sizeof(data_type) * array_size
Ejemplo:
declarar una array que puede contener valores de 4 enteros
int arr[4];
En este caso, sizeof(int) = 4. Por lo tanto, se reservan 4*4 = 16 bytes de memoria para la array.
Declaración de array y ejemplo de inicialización:
int arr[5] = {10, 20, 30, 40, 50};
Se puede acceder a los elementos de la array mediante índices, que van de 0 a (array_size-1).
A continuación se muestra el código de muestra para el uso de arrays en C:
C
// C implementation to demonstrate // the usage of arrays #include <stdio.h> int main() { // Array Indexs-0 1 2 3 4 int arr[5] = { 10, 20, 30, 40, 50 }; int size = sizeof(arr); printf("Size of array is %d\n", size); printf("Data at index 2 is %d\n", arr[2]); }
Size of array is 20 Data at index 2 is 30
Estructuras
Hemos utilizado tipos de datos primitivos para almacenar datos. Pero, ¿y si los datos que queremos almacenar son más complejos?
Consideremos un ejemplo, queremos almacenar información de los estudiantes en una clase en una sola variable. Entonces, un estudiante tiene:
- Número de rollo
- Nombre
Aquí, el número de rollo es de tipo entero y el nombre es de tipo string (array de caracteres).
Aquí está la solución: estructuras
- La estructura es una colección de variables (pueden ser de diferentes tipos de datos), bajo un solo nombre.
- También es un segmento de memoria contiguo como una array, pero permite miembros de datos de diferentes tipos de datos.
Sintaxis para definir estructuras:
struct structure_name { datatype member1_name; datatype member2_name; .. datatype membern_name; };
Ejemplo:
struct student { int roll_number; char name[20]; };
Ahora tenemos un tipo de datos recién definido, struct student. Podemos crear sus variables.
Sintaxis para la declaración de variables:
struct structure_name variable_name;
Ejemplo:
struct student ram; // Members of structures can // be accessed using "." operator stu.roll_number = 64; stu.name = “Saurabh”;
No se asigna memoria cuando definimos una estructura.
El tamaño de la estructura es igual a la cantidad total de espacio consumido por cada miembro de datos.
Ejemplo:
En caso de estructura de estudiante, es 4 + 20 = 24 bytes
A continuación se muestra la ilustración de las estructuras con la ayuda del código:
C
// C implementation to demonstrate // the usage of structures #include <stdio.h> #include <string.h> // Structure Definition struct student { // data members int roll_no; // 4 bytes char name[20]; // 20 bytes }; int main() { // Structure variable Declaration struct student stu; stu.roll_no = 64; strcpy(stu.name, "Saurabh"); printf("Structure Data\n"); printf("Roll No: %d\n", stu.roll_no); printf("Name: %s\n", stu.name); int size = sizeof(stu); printf("Size of Structure student"); printf("is %d", size); }
Structure Data Roll No: 64 Name: Saurabh Size of Structure studentis 24
Punteros
- Los punteros son el tipo especial de variables que almacena la dirección, en lugar del valor de la variable.
- Se utilizan para el acceso indirecto de variables.
- Si var es el nombre de la variable, &var proporciona la dirección de var .
Recordó el símbolo de ampersand (&) utilizado en la función scanf
scanf(“%d”, &var);
Esto se debe a que asignamos los valores escaneados a la ubicación de memoria de var .
No nos interesan las direcciones, sino los valores almacenados en esa dirección.
Sintaxis para la declaración de puntero:
data_type* pointer_name; // (* = asterisk)
Ejemplo:
int* ptr;
El puntero puede apuntar a cualquier tipo de datos
. Puede contener la dirección de cualquier variable del tipo de datos al que apunta.
Una variable de puntero no inicializada tiene un valor NULL.
Ejemplo:
int* ptr; int num = 5; ptr = #
Para obtener el valor en la dirección a la que apunta el puntero, usamos el operador asterisco (*).
Entonces, en el ejemplo anterior, el ptr tiene la dirección 250 y el valor en la dirección es 5.
Por lo tanto, *ptr es igual a 5.
A continuación se muestra la ilustración de los punteros con la ayuda del código:
C
// C implementation to demonstrate // pointers in C #include <stdio.h> int main() { int* ptr; int num = 5; ptr = # // This gives address of num printf("Value at ptr is %p\n", ptr); // This gives value at num printf("Value at *ptr is %d\n", *ptr); }
Value at ptr is 0x7ffdff4dca9c Value at *ptr is 5
El tamaño de la variable Pointer siempre es constante en un sistema, independientemente del tipo de datos al que apunte y, por lo general, es de 8 bytes.
Puntero a la Estructura
- El puntero a la estructura se puede declarar como variable normal.
Ejemplo:
struct student *p;
Aquí, p es puntero y *p es la estructura
Por lo tanto, para acceder a los miembros de datos, tenemos que usar
(*p).roll_no (*p).name
C proporciona un operador especial para acceder a los miembros de datos a través de un puntero, es decir, -> operador de flecha.
Nota: (*p).x equivalente a p->x
A continuación se muestra la ilustración de los punteros a la estructura:
C
// C implementation to illustrate // the code of the structures #include <stdio.h> #include <stdlib.h> // Structure Definition struct student { int roll_no; char name[20]; }; int main() { struct student* p; p = (struct student*) malloc(sizeof(struct student)); // Arrow operator p->roll_no = 99; printf("The value at roll"); printf("number is %d", p->roll_no); return 0; }
The value at rollnumber is 99
Funciones
- Una función es un bloque de código que realiza una tarea específica.
- Una función puede tener una entrada, realizar tareas y luego proporcionar alguna salida.
En el ejemplo anterior, estamos dando entradas como 2 números a una función. Está realizando la función de adición. Luego, se devuelve la suma de los dos números ingresados.
- Las entradas se llaman son parámetros de la función.
- La salida se llama valor de retorno.
Las funciones se pueden clasificar en dos categorías:
Funciones integradas o predefinidas
Estos se definen en la biblioteca estándar del lenguaje C. No tenemos que definir estas funciones, lo único que se necesita es llamar a estas funciones. Solo necesitamos conocer la sintaxis adecuada y podemos usar fácilmente estas funciones.
Ejemplo:
printf(), scanf(), main(), etc. son funciones predefinidas.
Funciones definidas por el usuario
- Estas son las funciones definidas por el programador para ejecutar alguna tarea en el programa.
- Dividir un problema complejo en partes más pequeñas hace que nuestro programa sea fácil de entender.
Para usar la función definida por el usuario, tenemos que realizar dos pasos
- Definición de función
- función de llamada
Sintaxis de definición de función:
return_type function_name(<parameters_list>) { --tasks/operations-- return return_value; }
Nota:
- Una función puede tener 0 o más parámetros.
- Una función puede tener 0 o 1 valor de retorno.
- La función que no devuelve nada tiene el tipo de retorno nulo.
A continuación se muestra la ilustración de las funciones en C:
C
// C implementation to // illustrate functions in C #include <stdio.h> // program to demonstrate functions // function definition // function to print something void print() { printf("GeeksforGeeks\n"); } // Function to add two numbers int add(int a, int b) { int sum; sum = a + b; return sum; } // Main Function int main() { int res; // Function call print(); res = add(5, 7); printf("Sum is %d", res); }
GeeksforGeeks Sum is 12
Nota: El tipo pasado en la llamada a la función debe ser compatible con el recibido por el cuerpo de la función como parámetro. De lo contrario, causará un error de compilación.
Clasificación de funciones según el tipo de llamada:
Llamada de función pasando valor
- Cuando llamamos a la función pasando valor (como en el programa anterior), los valores de las variables originales no se ven afectados.
- En lugar de enviar la variable original, envía una copia de una variable.
A continuación se muestra la ilustración de la llamada a la función pasando valor en C:
C
// C implementation for the // function call by passing value #include <stdio.h> // Function pass by value void increase_by_one(int x) { x++; } int main() { int num = 5; printf("Value before function"); printf(" call %d\n", num); increase_by_one(num); printf("Value after function"); printf(" call %d\n", num); }
Value before function call 5 Value after function call 5
En este programa, hemos pasado la variable a a la función, que tenía el valor 5. Luego, incrementamos el valor de la variable recibida por la función, es decir, x en 1. Entonces, el valor de x ahora es 6. Pero este cambio es limitado. solo para el alcance de la función. El valor de a en principal seguirá siendo 5.
Llamada de función pasando dirección
- Si queremos cambiar el valor de la variable pasada, tenemos que pasar la variable por dirección.
- Este método usa la misma variable en lugar de crear su nueva copia.
A continuación se muestra el código de la llamada a la función pasando la dirección:
C
// C implementation to demonstrate // the usage of function call by // passing reference #include <stdio.h> // function to demonstrate // call by value void increase_by_one(int* x) { (*x)++; } int main() { int num = 5; printf("Value before function"); printf(" call %d\n", num); increase_by_one(&num); printf("Value after function"); printf(" call %d\n", num); }
Value before function call 5 Value after function call 6
Como estamos pasando la dirección de la variable, tenemos que recibirla como variable de puntero.
Función: pasar array como parámetro
C
// C implementation to demonstrate // the example of the passing as // parameter in the function #include <stdio.h> // Function to print the array void print_array(int arr[], int n) { // N is size of array int i; for (i = 0; i < n; i++) printf("%d ", arr[i]); } int main() { int arr[5] = { 10, 20, 30, 40, 50 }; // Function Call print_array(arr, 5); }
10 20 30 40 50
Tipo de fundición
La conversión de tipos es básicamente la conversión de un tipo de datos en otro.
Sintaxis de conversión de tipos:
var2 = (datatype2) var1 where, var1 is of datatype1 & var2 is of datatype2
Ejemplo:
Si desea convertir el valor de una variable entera en una variable flotante
float x = (float)7/5;
Para obtener más información sobre el encasillamiento, consulte Conversión de tipo en C
Asignación de memoria dinámica
Como sabes, una array es una colección de un número fijo de valores. Una vez que se declara el tamaño de una array, no puede cambiarlo.
A veces, el tamaño de una array que declara puede ser insuficiente. Para resolver este problema, puede asignar memoria dinámicamente en tiempo de ejecución. Esto se conoce como asignación de memoria dinámica.
Funciones predefinidas utilizadas en la asignación de memoria dinámica:
1. malloc()
- malloc significa asignación de memoria.
- La función malloc() reserva un bloque de memoria del número especificado de bytes y void* que se puede convertir en punteros de cualquier forma.
Sintaxis de malloc():
pointer_name = (cast_datatype*)malloc(size);
2. gratis()
- La memoria asignada dinámicamente mediante malloc() no se libera por sí sola. Debe usar explícitamente free() para liberar este espacio.
Sintaxis gratis:
free(pointer_name);
Nota: estas funciones se declaran en el archivo de encabezado stdlib.h. Para usar estas funciones, primero debe incluir este encabezado.
A continuación se muestra la ilustración de la asignación de memoria dinámica en C:
C
// C implementation to demonstrate // the code the Dynamic Memory // Allocation #include <stdio.h> #include <stdlib.h> int main() { int* ptr; int n = 5, i; ptr = (int*)malloc(n * sizeof(int)); for (i = 0; i < n; i++) ptr[i] = i; printf("\nArray Elements are\n"); for (i = 0; i < n; i++) printf("%d ", ptr[i]); free(ptr); }
Array Elements are 0 1 2 3 4
Para obtener más información sobre la asignación de memoria dinámica, consulte Asignación de memoria dinámica en C