1123 lines
26 KiB
Markdown
1123 lines
26 KiB
Markdown
# Curso programación con lenguaje C de Juantxi Rodríguez
|
||
|
||
|
||
|
||
En estos repositorios dejo algunas prácticas que hice con el latín de los lenguajes de programación. No todo es perfecto, pero en su momento lo hice con mucho cariño.
|
||
|
||
Los ejercicios y apuntes los tome en clases de Juantxi Rodríguez (juantxiacademiahiperion@gmail.com). No es un curso completo, son meros apuntes personales.
|
||
|
||
**Índice**
|
||
- [Curso programación con lenguaje C de Juantxi Rodríguez](#curso-programación-con-lenguaje-c-de-juantxi-rodríguez)
|
||
- [**1. Intro**](#1-intro)
|
||
- [**1.1 De interés**](#11-de-interés)
|
||
- [**1.2 Guías**](#12-guías)
|
||
- [**1.3 Documentación concreta**](#13-documentación-concreta)
|
||
- [**1.4 Notas**](#14-notas)
|
||
- [**2. Sentencias de control**](#2-sentencias-de-control)
|
||
- [**2.1 Condicionales**](#21-condicionales)
|
||
- [**2.1.1.** ***if***](#211-if)
|
||
- [**2.1.2.** ***if-else (anidadas)***](#212-if-else-anidadas)
|
||
- [**2.1.3** ***switch***](#213-switch)
|
||
- [**2.2 Repetitivas**](#22-repetitivas)
|
||
- [**2.2.1** ***for → Desde***](#221-for--desde)
|
||
- [**2.2.2** ***while → mientras***](#222-while--mientras)
|
||
- [**2.2.3** ***do-while → repetir mientras***](#223do-while--repetir-mientras)
|
||
- [Notas](#notas)
|
||
- [**2.2.4 Bucles ¿Conozco de antemano cuántas veces se va a repetir?**](#224-bucles-conozco-de-antemano-cuántas-veces-se-va-a-repetir)
|
||
- [Ejercicio](#ejercicio)
|
||
- [**3. Arrays**](#3-arrays)
|
||
- [**3.1 Carga de un array**](#31-carga-de-un-array)
|
||
- [**3.2 Mostrar un array**](#32-mostrar-un-array)
|
||
- [**3.3 Buscar un elemento**](#33-buscar-un-elemento)
|
||
- [**3.4 Eliminar un elemento de un array**](#34-eliminar-un-elemento-de-un-array)
|
||
- [**3.5 Array bidimensionales - matrices**](#35-array-bidimensionales---matrices)
|
||
- [**4. Cadenas de caracteres**](#4-cadenas-de-caracteres)
|
||
- [**4.1 strlen**](#41-strlen)
|
||
- [**4.2 strcmp**](#42-strcmp)
|
||
- [**4.3 strcpy**](#43-strcpy)
|
||
- [**4.4 strrev**](#44-strrev)
|
||
- [**5. Estructuras**](#5-estructuras)
|
||
- [**5.1 Estructuras anidadas**](#51-estructuras-anidadas)
|
||
- [**6. Funciones**](#6-funciones)
|
||
- [EJERCICIOS](#ejercicios)
|
||
- [**Funciones para el tres en raya**](#funciones-para-el-tres-en-raya)
|
||
- [**Hundir la flota**](#hundir-la-flota)
|
||
- [**Arrays de estructuras.**](#arrays-de-estructuras)
|
||
- [Menú](#menú)
|
||
|
||
# **1. Intro**
|
||
## **1.1 De interés**
|
||
Lenguajes más usados según tiobe: <https://www.tiobe.com/tiobe-index/>
|
||
|
||
## **1.2 Guías**
|
||
Guía: <http://conclase.net/c/curso/cap0>
|
||
|
||
w3school <https://www.w3schools.in/c-tutorial/>
|
||
|
||
Codeforwin <https://codeforwin.org/2017/08/introduction-c-programming.html>
|
||
|
||
Documentación: <https://devdocs.io/c/>
|
||
|
||
Chuleta: <https://cheatography.com/ashlyn-black/cheat-sheets/c-reference/>
|
||
|
||
## **1.3 Documentación concreta**
|
||
Lista de funciones: [https://es.wikipedia.org/wiki/Anexo:Funciones_de_la_biblioteca_est%C3%A1ndar_de_C](https://es.wikipedia.org/wiki/Anexo:Funciones_de_la_biblioteca_estándar_de_C)
|
||
|
||
Lista de todas las especificaciones de formato: <https://codeforwin.org/2015/05/list-of-all-format-specifiers-in-c-programming.html>
|
||
|
||
## **1.4 Notas**
|
||
|
||
Lenguaje C → Estructurado
|
||
|
||
Java → orientado a objetos
|
||
|
||
C++ → orientado a objetos
|
||
|
||
C# → orientado a objetos
|
||
|
||
|
||
Windows
|
||
|
||
- Dev C++
|
||
- CodeBlocks
|
||
|
||
Mac
|
||
|
||
- Clion
|
||
- Xcode
|
||
|
||
Linux
|
||
|
||
- Línea de comandos
|
||
- nano
|
||
- gedit
|
||
|
||
./ ….
|
||
|
||
gcc
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.001.png)
|
||
|
||
|
||
Variables
|
||
|
||
- Numéricos
|
||
- Enteros int shoert long
|
||
- Reales float double
|
||
- Otros tipos
|
||
- byte
|
||
- Caracter char
|
||
|
||
\* → Puntero. Tipo de dato que almacena una dirección de memoria.
|
||
|
||
|
||
Constantes
|
||
|
||
`#define NOMBRE valor`
|
||
|
||
`nombre = valor; `
|
||
|
||
`int numero1;`
|
||
|
||
|
||
Definición:
|
||
|
||
- tipo nombre ;
|
||
|
||
nombre: No puede empezar por un número. No puede estar reservado
|
||
|
||
La diferencia principal entre constante y variable es que una constante no se puede modificar una vez se define, mientras que una variable sí.
|
||
|
||
Especificadores de formato:
|
||
|
||
`%d` → entero
|
||
|
||
`%f` → reales
|
||
|
||
`%c` → 1 carácter
|
||
|
||
`%s` → cadenas de caracteres
|
||
|
||
Allá donde veas un `&` se trata de una dirección de memoria.
|
||
|
||
Asignación `=`
|
||
|
||
Aritmético `+ - * / %`
|
||
|
||
Relacionales `== != > < >= <=`
|
||
|
||
Lógicos `! NOT && AND || OR`
|
||
|
||
|
||
|
||
Crear un programa en C que pida al usuario dos números enteros y nos muestre por pantalla su suma, su diferencia, su producto y la división del primero entre el segundo.
|
||
|
||
pide2NumerosYCalcula.c
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.002.png)
|
||
|
||
He hecho otro programa que compara 3 números e indica el valor mayor [ compara3Numeros.c ], pero no tiene bien la estructura de control. Si pones una letra no da error sino que dice un resultado extraño:
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.003.png)
|
||
|
||
# **2. Sentencias de control**
|
||
## **2.1 Condicionales**
|
||
### **2.1.1.** ***if***
|
||
```
|
||
if(expresión){
|
||
<Instrucciones>
|
||
}else{
|
||
<Instrucciones>
|
||
}
|
||
```
|
||
### **2.1.2.** ***if-else (anidadas)***
|
||
```
|
||
if(expresión){
|
||
<Instrucciones>
|
||
}else if{
|
||
<Instrucciones>
|
||
}else{
|
||
<Instrucciones>
|
||
}
|
||
```
|
||
|
||
### **2.1.3** ***switch***
|
||
```
|
||
case
|
||
switch(){
|
||
case ___:
|
||
<Instrucciones>
|
||
break;
|
||
case ___:
|
||
<Instrucciones>
|
||
break;
|
||
default:
|
||
<Instrucciones>
|
||
}
|
||
```
|
||
|
||
Siempre tendrá valores constantes, no se pueden usar operadores. El switch se utiliza mucho para menus.
|
||
|
||
|
||
Para introducir funciones de operaciones aritméticas se debe invocar:
|
||
```
|
||
#include<math.h>
|
||
```
|
||
y cuando se compila se debe poner la opción -lm
|
||
|
||
Ejemplo de switch:
|
||
```
|
||
#include<stdio.h>
|
||
#include<math.h>
|
||
|
||
int main(){
|
||
/* Variables */
|
||
int menu, num1, num2;
|
||
float potencia;
|
||
|
||
/* Solicitamos valores para las variables */
|
||
printf("\nIntroduce el primer numero para operar\n");
|
||
scanf("%d", &num1);
|
||
printf("\nIntroduce el segundo numero para operar\n");
|
||
scanf("%d", &num2);
|
||
|
||
/* Elegir opción */
|
||
printf("\nIntroduce una opción del 1 al 5: ");
|
||
printf("\n1 Suma ");
|
||
printf("\n2 División");
|
||
printf("\n3 diferencia");
|
||
printf("\n4 producto");
|
||
printf("\n5 potencia\n");
|
||
|
||
scanf("%d", &menu);
|
||
|
||
/* Condicional case para seleccionar el número mayor */
|
||
switch (menu) {
|
||
|
||
case 1:
|
||
printf("\nEl resultado de la suma es: %d\n", num1+num2);
|
||
break;
|
||
|
||
case 2:
|
||
printf("\nEl resultado de la división es: %d\n", num1/num2);
|
||
break;
|
||
|
||
case 3:
|
||
printf("\nEl resultado de la resta es: %d\n", num1-num2);
|
||
break;
|
||
|
||
case 4:
|
||
printf("\nEl resultado de la multiplicación es: %d\n", num1\*num2);
|
||
break;
|
||
|
||
case 5:
|
||
potencia=pow(num1, num2);
|
||
printf("\nEl resultado de la división es: %f\n", potencia);
|
||
break;
|
||
|
||
default:
|
||
printf("\nNo es un valor correcto\n\n");
|
||
}
|
||
}
|
||
```
|
||
Para la potencia se usa la función pow de la biblioteca math
|
||
|
||
funciones de la biblioteca math.h en C: <https://platzi.com/tutoriales/1968-funciones-c/9103-todas-las-funciones-de-la-biblioteca-mathh-en-c/>
|
||
## **2.2 Repetitivas**
|
||
### **2.2.1** ***for → Desde***
|
||
```
|
||
for (init; condition; increment){
|
||
|
||
Instrucción 1;
|
||
Instrucción 2;
|
||
…
|
||
…
|
||
Instrucción 3;
|
||
}
|
||
```
|
||
### **2.2.2** ***while → mientras***
|
||
```
|
||
While (condition){
|
||
statement(s);
|
||
Incrementation;
|
||
}
|
||
```
|
||
|
||
### **2.2.3** ***do-while → repetir mientras***
|
||
```
|
||
do {
|
||
statement(s);
|
||
}while( condition );
|
||
```
|
||
### Notas
|
||
|
||
**Main:**
|
||
|
||
`void main (void)` [turbo C]
|
||
|
||
`int main (void)` Si devuelve 0 la ejecución correcta
|
||
|
||
`return 0;` Si no está es como si estuviera
|
||
|
||
`int main(int argc, char \*argv[])` Para recibir argumentos
|
||
|
||
`int argc` n.º de argumentos que tiene el programa
|
||
|
||
`char \*argv[]` Los propios argumentos
|
||
|
||
|
||
**Especificadores de formato:**
|
||
|
||
`%d %i` → entero
|
||
|
||
`%f` → reales
|
||
|
||
`%c` → 1 carácter
|
||
|
||
`%s` → cadenas de caracteres
|
||
|
||
Más info:
|
||
<https://codeforwin.org/2015/05/list-of-all-format-specifiers-in-c-programming.html>
|
||
|
||
**Funciones `stdlib.h`**
|
||
|
||
`atoi` - Esta función devuelve el número integral convertido como un valor int. Si no se ha podido realizar una conversión válida, devuelve cero.
|
||
|
||
`Itoa` - convierte el tipo de datos int en tipo de datos string. La sintaxis de esta función es la siguiente
|
||
```
|
||
char \* itoa ( int valor, char \* str, int base );
|
||
```
|
||
### **2.2.4 Bucles ¿Conozco de antemano cuántas veces se va a repetir?**
|
||
|
||
**Si lo sabemos** → `for` . También para recorrer arrays. Se maneja con un índice que suele ser `int i`
|
||
|
||
inicio → condición → paso
|
||
```
|
||
for (inicio; condición; paso){
|
||
- - - - - - - -
|
||
}
|
||
```
|
||
```
|
||
for(i=1;i<100;i++){
|
||
printf(“%d “. i”);
|
||
}
|
||
```
|
||
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.004.png" alt="esbozo"><figcaption><b>Captura a esbozos de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
|
||
|
||
**No lo sabemos** → Podemos elegir entre:
|
||
|
||
- `while` - 1º evalúa y después pide
|
||
|
||
- `do while` – al menos se ejecuta una vez. 1º pide después evalúa. Se usa en menús
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.005.png" alt="esbozo"><figcaption><b>Captura a esbozos de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
### Ejercicio
|
||
Pedir al usuario dos enteros y sacar por pantalla todos los números pares entre el más pequeño y el más grande.
|
||
```
|
||
#include<stdio.h>
|
||
|
||
int main (){
|
||
|
||
int num1, num2, menor, mayor, i;
|
||
|
||
printf("\nIntroduce un número donde empieza el conteo de pares: ");
|
||
|
||
scanf("%d", &num1);
|
||
|
||
printf("\nIntroduce un número para finalizar el conteo de pares: ");
|
||
|
||
scanf("%d", &num2);
|
||
|
||
if(num1<num2){
|
||
|
||
menor=num1;
|
||
|
||
mayor=num2;
|
||
|
||
}else{
|
||
|
||
menor=num2;
|
||
|
||
mayor=num1;
|
||
|
||
}
|
||
|
||
for(i=menor; i<=mayor; i++){
|
||
|
||
if (i%2==0){
|
||
|
||
printf("%d ",i);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//hacer una cuenta atrás desde un número pedido al usauario
|
||
|
||
}
|
||
```
|
||
|
||
Programa que pida números al usuario hasta que este introduzca un número impar. Cuando introduzca el par el programa mostrará la media de los números introducidos.
|
||
```
|
||
#include<stdio.h>
|
||
|
||
int main (){
|
||
|
||
int num;
|
||
|
||
int suma=0;
|
||
|
||
float media;
|
||
|
||
int contador=0;
|
||
|
||
printf("\nSi el número que introduces es par");
|
||
|
||
do{
|
||
|
||
printf("\nIntroduce un número: ");
|
||
|
||
scanf("%d", &num);
|
||
|
||
suma=suma+num;
|
||
|
||
contador++;
|
||
|
||
} while (num%2==0);
|
||
|
||
media=(float)suma/contador;
|
||
|
||
printf("%f ",media);
|
||
|
||
}
|
||
```
|
||
|
||
Conversión binario
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.006.png" alt="esbozo"><figcaption><b>Captura de la pantalla de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
|
||
Ejercicio 1: Programa que pida números al usuario hasta que este introduzca un número que sea primo.
|
||
```
|
||
#include<stdio.h>
|
||
|
||
int main (){
|
||
|
||
// Variables
|
||
|
||
int numero=0;
|
||
|
||
int divisores=0;
|
||
|
||
int primo=0; // primo = 0 no primo = 1
|
||
|
||
// Solicitar numero entero hasta valor -1
|
||
|
||
do
|
||
|
||
{
|
||
|
||
printf("\nIntroduce un número, si es primo se cerrará el programa: ");
|
||
|
||
scanf(" %d",&numero);
|
||
|
||
if(numero!=-1 && numero>0)
|
||
|
||
{
|
||
|
||
// el numero es mayor que 0, comprobar si es primo
|
||
|
||
primo=0;
|
||
|
||
divisores=2;
|
||
|
||
while(divisores<numero && primo!=1)
|
||
|
||
{
|
||
|
||
if(numero%divisores==0) primo=1;
|
||
|
||
divisores++;
|
||
|
||
}
|
||
|
||
// Si primo vale 0 es que el numero no es primo
|
||
|
||
printf("\nEl numero %d no es primo",numero);
|
||
|
||
printf("\n");
|
||
|
||
}
|
||
|
||
// Si primo vale 1 es que el numero es primo y utilizará la condición para salir del bucle
|
||
|
||
} while(primo==1);
|
||
|
||
return 0;
|
||
|
||
}
|
||
```
|
||
|
||
CORRECIÓN:
|
||
```
|
||
Esprimo=1;
|
||
|
||
for(i=2;i<numero;i++){
|
||
|
||
if(numero%i==0){
|
||
|
||
esprimo=0;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if(esprimo==1){
|
||
|
||
----es primo ---
|
||
|
||
}else{
|
||
|
||
---no es primo---
|
||
|
||
}
|
||
```
|
||
|
||
|
||
Ejercicio 2: Programa que pida dos números al usuario. El programa comprobará si esos dos números son números amigos. Dos números amigos son dos números enteros positivos a y b tales que la suma de los divisores propios de uno es igual al otro número y viceversa. Por ejemplo el 220 y el 284 son números amigos ya que sus divisores son:
|
||
|
||
- De 220 son 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 y 110, que suman 284;
|
||
- De 284 son 1, 2, 4, 71 y 142, que suman 220.
|
||
|
||
Hay que tener en cuenta que se trata de divisores propios, es decir, no se tiene en cuenta para la
|
||
|
||
suma el propio número.
|
||
|
||
|
||
Ejercicio 3: Programa que pida tres números entero al usuario y a continuación muestre un menú como el siguiente:
|
||
|
||
1. Sumar los dos primeros números.
|
||
1. Multiplicar el segundo con el tercero.
|
||
1. Mostrar los tres números en orden.
|
||
1. Comprobar si el primero es primo.
|
||
1. Comprobar si el segundo es un número perfecto (un número perfecto es un número entero positivo tal que es igual a la suma de sus divisores propios positivos. Dicho de otra forma, un número perfecto es aquel que es amigo de sí mismo. Por ejemplo el 28, cuyos divisores son 28 = 1 + 2 + 4 + 7 + 14 es perfecto.
|
||
1. Salir.
|
||
|
||
El programa se repetirá hasta que el usuario pulse la opción de salir. Si el usuario introduce cualquier opción que no sea 1, 2, 3, 4, 5 o 6 se le mostrará un mensaje de “opción no disponible”.
|
||
|
||
Al comienzo cuando se piden los tres números al usuario el programa se debe asegurar de que el usuario introduce números positivos. En caso de que no meta un número positivo se lo vuelve a pedir.
|
||
|
||
|
||
# **3. Arrays**
|
||
estáticas y homogéneas
|
||
|
||
unidimensionales → vectores
|
||
|
||
bidimensionales → matrices
|
||
|
||
tridim….
|
||
|
||
…
|
||
|
||
`Tipo nombre [tamaño];`
|
||
|
||
El tamaño se puede dar con una constante: define
|
||
```
|
||
#define TAM 10
|
||
|
||
int vector[TAM]
|
||
```
|
||
Elemento a elemento.
|
||
|
||
Cada una de las celdas de memoria tendrá una numeración/índice que empieza por 0. Están indizadas.
|
||
## **3.1 Carga de un array**
|
||
```
|
||
vector[4] =12;
|
||
|
||
for (i=0; i<TAM; i++){
|
||
|
||
` `printf(,,,,,);
|
||
|
||
` `scanf(“%d ”, &vector[i]);
|
||
|
||
}
|
||
```
|
||
## **3.2 Mostrar un array**
|
||
```
|
||
for(i=0; i<TAM; i++){
|
||
|
||
` `printf(“%d “, vector [i]);
|
||
|
||
}
|
||
```
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.007.png" alt="esbozo"><figcaption><b>Captura de esbozo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
## **3.3 Buscar un elemento**
|
||
|
||
```
|
||
for(i=o; i<TAM; i++){
|
||
if(vector[i]==buscado){
|
||
}
|
||
}
|
||
```
|
||
|
||
Variable flag para parar cuando se encuentra
|
||
|
||
int encontrado 1
|
||
|
||
no encontrado 0
|
||
```
|
||
` `for(i=o; i<TAM; i++){
|
||
` `if(vector[i]==buscado){
|
||
` `encontrado=1
|
||
` `}
|
||
` `}
|
||
if (encontrado ==0){
|
||
` `printf(“Ese número no está en el array”);
|
||
}else {
|
||
` `printf(“Ese número sí está en el array”);
|
||
}
|
||
```
|
||
|
||
## **3.4 Eliminar un elemento de un array**
|
||
Se sustituye el elemento con un 0
|
||
|
||
o
|
||
|
||
Se almacena la posición del elemento a eliminar y el resto de elementos se traen hacía atrás
|
||
|
||
encontrado + posición
|
||
|
||
Se puede resumir en posición
|
||
```
|
||
posicion=-1
|
||
|
||
for(i=0,i<TAM; i++){
|
||
|
||
` `if(vector[i]==buscado){
|
||
|
||
` `posicion=i;
|
||
|
||
` `}
|
||
|
||
}
|
||
|
||
if(posicion==-1){
|
||
|
||
` `printf(“El elemento que quieres no esta”);
|
||
|
||
}else{
|
||
|
||
` `for(i=posicion;i<TAM;i++){
|
||
|
||
` `vector[i]=vector[ì+1];
|
||
|
||
` `}
|
||
|
||
` `printf(“Elemento eliminado”);
|
||
|
||
}
|
||
```
|
||
Con una letra se vuelve loco:
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.009.png" alt="esbozo"><figcaption><b>Captura a la pantalla de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
Un return 0 significa que todo ha ido bien.
|
||
|
||
Cuando el valor es otro significa que no ha ido bien.
|
||
## **3.5 Array bidimensionales - matrices**
|
||
|
||
Anteriormente hemos visto los unidimensionales
|
||
|
||
` `unidimensionales → vectores
|
||
|
||
` `bidimensionales → matrices
|
||
|
||
`matriz [filas] [columnas]`
|
||
|
||
Ejemplo
|
||
|
||
int m1[3] [4]
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.010.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
|
||
```
|
||
m1[0][2]=12;
|
||
```
|
||
```
|
||
m1[1] [3]=22;
|
||
```
|
||
```
|
||
m1[2] [0]=14;
|
||
```
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.011.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
Para darle valor a las posiciones hay que usar un doble bucle.
|
||
|
||
` `Un for externo para las filas
|
||
|
||
` `Un for interno para las columnas
|
||
```
|
||
for(i=0; i<FILAS; i++){ //externo filas
|
||
` `for(j=0; j<COLUMNAS; j++){ //interno columnas
|
||
` `printf(“ fila %d y columna %”, i , j)
|
||
` `scanf(“%d”, &m1[i][j]);
|
||
` `}
|
||
}
|
||
```
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.012.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
# **4. Cadenas de caracteres**
|
||
Parecido a los arrays.
|
||
|
||
Estructura de datos chav \0
|
||
|
||
que termina en un carácter dinal
|
||
|
||
‘’ 1 carácter
|
||
|
||
“” cadenas
|
||
|
||
`char cadena[n]`
|
||
|
||
Podremos usar todas las opciones de la librería:
|
||
|
||
#include<string.h>
|
||
|
||
`String` → Cadena de caracteres
|
||
|
||
Ejemplo:
|
||
```
|
||
char cadena[50];
|
||
|
||
printf(“\nIntroduce una cadena: ”);
|
||
|
||
fflush(stdin);
|
||
```
|
||
Tenemos 3 vías para almacenar en el char:
|
||
```
|
||
scanfc(“%s”, cadena); ##### sin & porque ya tiene la cadena |||| La más fácil pero la más insegura
|
||
```
|
||
```
|
||
gets(cadena); ###### Da problemas en Mac y Linux.
|
||
```
|
||
```
|
||
Scanf(“%[^\n]”, cadena);
|
||
```
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.014.png)
|
||
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.015.png)
|
||
|
||
strlen → Longitud de cadenas
|
||
|
||
strcmp → Comparar cadenas
|
||
|
||
strcpy → Asignar una cadena a otra
|
||
|
||
|
||
## **4.1 strlen**
|
||
|
||
`int strlen(char\*cad);` → int longitud;
|
||
```
|
||
…
|
||
longitud=strlen(cadena3);
|
||
printf(“\n …… ”, longitud);
|
||
printf(“\n ….. ”,strlen(cadena));
|
||
```
|
||
|
||
|
||
## **4.2 strcmp**
|
||
String comparar
|
||
|
||
`int strcmp(char\*cad1, char\*cad2);`
|
||
|
||
Resultados:
|
||
|
||
` `0 sin iguales
|
||
|
||
` `<0 cad1 es anterior a cad2
|
||
|
||
` `>0 cad2 es anterior a cad1
|
||
```
|
||
if (strcmp(cadena2,cadena3)==0){
|
||
` `printf(“\n son iguales”);
|
||
}else{
|
||
` `printf(“\n no son iguales”);
|
||
}
|
||
```
|
||
|
||
## **4.3 strcpy**
|
||
String copy
|
||
|
||
`char cadena1[5];`
|
||
|
||
`char cadena2[50];`
|
||
|
||
A cadena1 asignarle el contenido de cadena2.
|
||
```
|
||
cadena1=cadena2 X
|
||
```
|
||
```
|
||
strcpy(cadena1, cadena2);
|
||
```
|
||
` `destino origen
|
||
|
||
Sigue la misma nomenclatura de lo anteriormente visto:
|
||
|
||
`Numero=20;`
|
||
|
||
|
||
## **4.4 strrev**
|
||
String reverse
|
||
|
||
**Ejercicio**:
|
||
|
||
Programa en C que pida al usuario 2 cadenas de 100 caracteres y les cargue información. Después
|
||
|
||
- las muestra
|
||
- indicará la longitud de cada una
|
||
- indicará si son iguales entre ellas o no
|
||
- copia el contenido de la primera en la segunda y mostrar de nuevo ambás.
|
||
```
|
||
#include<stdio.h>
|
||
#include<stdlib.h>
|
||
#include<string.h>
|
||
|
||
int main(){
|
||
/* Variables */
|
||
char cadena1[100];
|
||
char cadena2[100];
|
||
int longitud;
|
||
|
||
printf("\nintroduce la primera cadena: ");
|
||
fflush(stdin);
|
||
scanf("%[^\n]", cadena1);
|
||
|
||
fflush(stdin);
|
||
printf("\nintroduce la segunda cadena: ");
|
||
fflush(stdin);
|
||
scanf("%[^\n]", cadena2);
|
||
/* Mostrar */
|
||
printf("\nCadena 1: %s", cadena1);
|
||
printf("\nCadena 2: %s", cadena2);
|
||
|
||
/* indicará la longitud de cada una */
|
||
longitud=strlen(cadena1);
|
||
printf("\nLa Cadena 1 mide: %d", longitud);
|
||
|
||
longitud=strlen(cadena2);
|
||
|
||
printf("\nLa Cadena 2 mide: %d", longitud);
|
||
|
||
/* indicará si son iguales entre ellas o no */
|
||
|
||
if (strcmp(cadena1,cadena2)==0){
|
||
printf("\n son iguales");
|
||
}else{
|
||
printf("\n no son iguales");
|
||
if(strcmp(cadena1, cadena2)<0){
|
||
printf("\nCadena 1 es alfabeticamente anterior a cadena2");
|
||
}else{
|
||
printf("\nCadena 2 es alfabeticamente anterior a cadena 1");
|
||
}
|
||
}
|
||
|
||
/* copia el contenido de la primera en la segunda y mostrar de nuevo ambás.*/
|
||
|
||
strcpy(cadena2,cadena1);
|
||
|
||
printf("\nCadena 1: %s", cadena1);
|
||
|
||
printf("\nCadena 2: %s", cadena2);
|
||
|
||
}
|
||
```
|
||
|
||
# **5. Estructuras**
|
||
Son los tipos de datos definidos por el desarrollador.
|
||
|
||
Persona
|
||
|
||
Nombre → cad 50
|
||
|
||
edad → entero
|
||
|
||
email → cad 50
|
||
|
||
altura → real
|
||
|
||
Al principio del programa haremos una definición (No la variable).
|
||
```
|
||
struct persona{
|
||
char nombre[50];
|
||
int edad;
|
||
char email[50];
|
||
float altura;
|
||
};
|
||
```
|
||
Cada uno de los datos se llaman miembro (o también llamado campo).
|
||
|
||
Después se deben declarar las variables.
|
||
|
||
`struct persona p1;`
|
||
|
||
Para darle valor a cada uno de los campos hay que hacerlo uno a uno. Puede ser desordenado.
|
||
|
||
Utilizamos el operador `.`
|
||
|
||
El operador `.` se conoce como acceso a miembro de una estructura
|
||
|
||
|
||
Ejemplo:
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.016.png)
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.017.png)
|
||
|
||
## **5.1 Estructuras anidadas**
|
||
Para definir fecha se podría anidar dentro de la estructura otra estructura.
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.018.png)
|
||
|
||
Para acceder habría que poner las estructura anidada
|
||
|
||
![](img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.019.png)
|
||
|
||
# **6. Funciones**
|
||
|
||
Si decidimos hacer nuestras propias funciones
|
||
|
||
1. Prototipo → resumen
|
||
|
||
"dato devuelto" "nombre" "(argumentos)"
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.020.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
Los argumentos pueden ser varios
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.021.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
|
||
|
||
1. Desarrollo de la función. Definición → Bloque de código
|
||
|
||
Es el cuerpo del código
|
||
|
||
|
||
3. Llamada (invocación al código)
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.022.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
|
||
Las funciones sirven para encapsular el código y para reutilizar el código
|
||
|
||
Propósitos:
|
||
|
||
- Modularización del código. Encapsular, mejora la visibilidad,
|
||
- Reutilización. No repetir la escritura del código, reutilizar el mismo. Cuanto más se programe, menos se tenga que programar.
|
||
-
|
||
# EJERCICIOS
|
||
## **Funciones para el tres en raya**
|
||
|
||
- Comprobar si gana el jugador 1 → Pueden devolver 0 si no ha ganado o 1 si ha ganado
|
||
- Comprobar si gana el jugador 2 → Pueden devolver 0 si no ha ganado o 1 si ha ganado. (Debe recibir como argumento matriz y carácter que defina el jugador)
|
||
- Empate
|
||
- Mostrar el tablero → `void`
|
||
|
||
Habría que pasar la matriz como argumento.
|
||
|
||
Probamos meter como argumento una matriz.
|
||
|
||
Solo se necesita indicar las columnas de la matriz: void cargar(int m[][COLUMNAS])
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.023.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
Un puntero es un tipo de variable capaz de almacenar una dirección de memoria.
|
||
|
||
` `Se suele decir que apunta a una dirección de memoria. Apunta a una variable o a una zona de memoria reservada.
|
||
|
||
Los vectores dinámicos reservan espacio de memoria para definir en la ejecución. Los punteros posibilitan hacer las matrices dinámicas.
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.024.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
El nombre de una array o de una cadena de caracteres es de por sí un puntero al primer elemento del array o de la cadena.
|
||
|
||
Los punteros permiten:
|
||
|
||
- arrays dinámicos
|
||
- estructuras dinámicas → Listas enlazadas
|
||
|
||
## **Hundir la flota**
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.025.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
## **Arrays de estructuras.**
|
||
(Examen de uni)
|
||
|
||
|
||
|
||
Funciona igual que un array teniendo en cuenta que cada posición es del tipo definido por nosotros.
|
||
|
||
Por ejemplo, si queremos almacenar en un array una agenda de contacto. De cada contacto tendremos:
|
||
|
||
- Nombre – Cadena de 60
|
||
- Teléfono – Cadena de 15
|
||
- Edad – Entero
|
||
|
||
En nuestra agenda habrá espacio para un máximo de 100 contactos.
|
||
|
||
<figure><img src="img/Aspose.Words.49c12fff-a89e-4b3d-97ea-e0f742c30e14.026.png" alt="esbozo"><figcaption><b>Captura de bosquejo de Juantxi Rodríguez</b></figcaption></figure>
|
||
|
||
```
|
||
#define MAX 100 /* Nos sirve para definir el tamaño. */
|
||
|
||
int main (){
|
||
struct contacto {
|
||
char nombre[60];
|
||
char telefono[15];
|
||
int edad;
|
||
}
|
||
// tipo nombre [Tamaño]
|
||
struct contacto agenda [MAX];
|
||
}
|
||
```
|
||
Para acceder a los datos se hace con el operador .
|
||
|
||
. Se llama acceso a miembro de una estructura
|
||
```
|
||
agenda[1].nombre
|
||
|
||
agenda[1].telefono
|
||
|
||
agenda[1].edad
|
||
```
|
||
|
||
## Menú
|
||
|
||
1 Cargar datos
|
||
|
||
2 Mostrar datos
|
||
```
|
||
#include<stdio.h>
|
||
#include<stdlib.h>
|
||
|
||
#define MAX 3
|
||
|
||
struct contacto {
|
||
char nombre[60];
|
||
char telefono[15];
|
||
int edad;
|
||
};
|
||
|
||
int main (){
|
||
|
||
// Defino variables
|
||
int menu;
|
||
int i;
|
||
|
||
// tipo nombre [Tamaño]
|
||
struct contacto agenda [MAX];
|
||
|
||
//elabora un menú con estas opciones: 1. cargar 2. mostrar 0 . salir
|
||
do{
|
||
printf("\nMenú");
|
||
printf("\n1 Cargar agenda");
|
||
printf("\n2 Mostrar agenda");
|
||
printf("\n0 Salir\n");
|
||
printf("\nIntroduce una opción reseñada: ");
|
||
|
||
fflush(stdin);
|
||
scanf("%d", &menu);
|
||
|
||
switch(menu){
|
||
|
||
case 1:
|
||
for(i=0; i<MAX; i++){
|
||
printf("\nIntroduce el nombre del contacto %d",i);
|
||
fflush(stdin);
|
||
|
||
scanf("%s", agenda[i].nombre);
|
||
printf("\nIntroduce teléfono del contacto %d",i);
|
||
fflush(stdin);
|
||
|
||
scanf("%s", agenda[i].telefono);
|
||
printf("\nIntroduce la edad del contacto %d",i);
|
||
fflush(stdin);
|
||
|
||
scanf("%d", &agenda[i].edad);
|
||
}
|
||
|
||
break;
|
||
|
||
case 2:
|
||
for(i=0; i<MAX; i++){
|
||
printf("\nEl contacto %d se llama %s, su numero de teléfono es %s y tiene %d años", i, agenda[i].nombre,agenda[i].telefono, agenda[i].edad);
|
||
}
|
||
|
||
break;
|
||
|
||
case 0:
|
||
break;
|
||
// ERROR EN EL MENÚ
|
||
|
||
default:
|
||
printf("\nNo es un valor correcto para este menu.\nVuelva a intentarlo\n\n");
|
||
}
|
||
|
||
}while ( menu != 0 );
|
||
|
||
return 0;
|
||
|
||
}
|
||
```
|