domingo, 23 de agosto de 2015

vectores en c++


← Uso de funcionesVectoresCadenas de caracteres →

Los vectores son una forma de almacenar datos que permiten contener una serie de valores del mismo tipo, cada uno de los valores contenidos tiene una posición asociada que se usará para accederlos. Está posición o índice será siempre un número entero positivo.
En C la cantidad de elementos que podrá contener un vector es fijo, y en principio se define cuando se declara el vector. Los vectores se pueden declarar de la siguiente forma:
 tipo_elemento nombre[largo];
Esto declara la variable nombre como un vector de tipo_elementos que podrá contener largo cantidad de elementos, y cada uno de estos elemento podrá contener un valor de tipo tipo_elemento.
Por ejemplo:
 double valores[128];
En este ejemplo declaramos un vector de 128 elementos del tipo double, los índices de los elementos irían entre 0 (para el primer elemento y 127 para el último).
De la misma forma que con las otras declaraciones de variables que hemos visto se le puede asignar un valor iniciar a los elementos.
O también se pueden declarar:
 tipo_elemento nombre[largo]={valor_0, valor_1, valor_2};
En caso estamos asignadole valores a los primeros 3 elementos del vector nombre. Notar que largo debe ser mayor o igual a la cantidad de valores que le estamos asignando al vector, en el caso de ser la misma cantidad no aporta información, por lo que el lenguaje nos permite escribir:
 tipo_elemento nombre[]={valor_0, valor_1, valor_2};
Que declarará nombre como el vector de largo 3.
Para acceder a un elemento accederemos a través de su posición. Es decir:
 tipo_elemento elemento;
 ...
 elemento = nombre[2];
Asumiendo que tenemos el vector anterior definido estaríamos guardando valor_2 en elemento.
Veamos algunos ejemplos:
/*
 * Ejemplo : El producto escalar de dos vectores
 */
#include <stdio.h>

double producto_escalar(double v1[], double v2[], int d);

int main()
{ 
 const int largo = 3;
 double vector_1[] = {5,1,0};
 double vector_2[] = {-1,5,3};

 double resultado = producto_escalar(vector_1, vector_2, largo);

 // imprime el resultado
 printf("(%f, %f, %f) . (%f, %f, %f) = %f\n",
  vector_1[0], vector_1[1], vector_1[2],
  vector_2[0], vector_2[1], vector_2[2],
  resultado);
 return 0;
}

/* producto escalar entre dos vectores */
double producto_escalar(double v1[], double v2[], int d)
{
 double resultado = 0;
 int i;
 for (i=0; i < d; i++) {
  resultado += v1[i] * v2[i];
 }
 return resultado;
}
En el ejemplo anterior usamos los vectores de C para representar vectores matemáticos y calcular el producto escalar entre ellos. Una peculiaridad que se puede notar es que al recibir un arreglo en una función no se especifica el largo, volveremos a esto en un capítulo posterior.
Otra función clásica es la búsqueda de un máximo o mínimo, que podemos escribirla de la siguiente manera:
int buscar_maximo(double valores[], int num_valores)
{
 int maximo_pos = 0;
 for (int i = 1; i < num_valores; i++) {
  if (valores[i] > valores[maximo_pos]) {
   maximo_pos = i;
  }
 }
 return maximo_pos;
}
Otro ejemplo sencillo, calcular el promedio de los valores.
double promedio(double valores[], int largo)
{
 double suma=0;
 for (int i=0;i<largo;i++) {
  suma+=valores[i];
 }
 return suma/largo;
}
Cuando una función recibe un vector por parámetro y cambia su contenido y el cambio es permanente (se ve aún fuera de la función). Esto puede parecer extraño después del énfasis que pusimos en resaltar que todos los parámetros de una función se reciben por valor, pero se aclarará en el siguiente capitulo.
Mientras tanto usemos esto para definir una función que le aplique otra función que recibe por parámetro a cada elemento del vector, guardando el resultado en el mismo vector y una llamada de ejemplo a esta.
void cuadrados(double vector[], int largo)
{
 for (int i=0;i<largo;i++) {
  vector[i]=cuadrado(vector[i]);
 }
}
...
double cuadrado(double valor) {
 return valor*valor;
}
...
 cuadrados(elementos,num_elem);
...
De la misma forma que venimos usando vectores de tipos básicos, podemos tener vectores de vectores, estos se declaran de la siguiente forma:
int matriz[3][7];
int tabla[3][4]={ { 1, 2, 3, 4},
    { 5, 6, 7, 8}, /* los espacios y saltos de líneas no son tomados en cuenta */
    { 9,10,11,12} };
double v[2][2][2];
...
printf("tabla[0][1]: %i\n", tabla[0][3]); // Imprime 4
printf("tabla[2][0]: %i\n", tabla[2][0]); // Imprime 9 
...
En este ejemplo tabla es un vector de longitud 3, cuyos elementos son vectores de longitud 4 de elementos de tipo int.
En resumen, suponiendo que v[n] es un vector de cualquier tipo de dato con n cantidad de posiciones, al vector v se le aplican las siguientes reglas:
  1. La primera posición siempre será v[0]
  2. La última posición es v[n-1]
  3. En versiones previas a C99 n es una constante definida antes de la declaración de v[n]+

funcion en c++

^
Las funciones son un conjunto de instrucciones que realizan una tarea específica. En general toman ciertos valores de entrada, llamados parámetros y proporcionan un valor de salida o valor de retorno; aunque en C++, tanto unos como el otro son opcionales, y pueden no existir.
Tal vez parezca un poco precipitado introducir este concepto tan pronto en el curso. Sin embargo, las funciones son una herramienta muy valiosa, y como se usan en todos los programas C++, creo que debemos tener, al menos, una primera noción de su uso. A fin de cuentas, todos los programas C++ contienen, como mínimo, una función.

Prototipos de funciones

^
En C++ es obligatorio usar prototipos. Un prototipo es una declaración de una función. Consiste en una presentación de la función, exactamente con la misma estructura que la definición, pero sin cuerpo y terminada con un ";". La estructura de un prototipo es:
[extern|static] <tipo_valor_retorno> [<modificadores>] <identificador>(<lista_parámetros>); 
En general, el prototipo de una función se compone de las siguientes secciones:
  • Opcionalmente, una palabra que especifique el tipo de almacenamiento, puede ser extern o static. Si no se especifica ninguna, por defecto será extern. No te preocupes de esto todavía, de momento sólo usaremos funciones externas, lo menciono porque es parte de la declaración.
  • El tipo del valor de retorno, que puede ser void, si no necesitamos valor de retorno. En C, si no se establece, será int por defecto, aunque en general se considera una mala técnica de programación omitir el tipo de valor de retorno de una función. En C++ es obligatorio indicar el tipo del valor de retorno.
  • Modificadores opcionales. Tienen un uso muy específico, de momento no entraremos en este particular, lo veremos en capítulos posteriores.
  • El identificador de la función. Es costumbre, muy útil y muy recomendable, poner nombres que indiquen, lo más claramente posible, qué es lo que hace la función, y que permitan interpretar qué hace el programa con sólo leerlos. Cuando se precisen varias palabras para conseguir este efecto se puede usar alguna de las reglas más usuales. Una consiste en separar cada palabra con un "_". Otra, que yo prefiero, consiste en escribir la primera letra de cada palabra en mayúscula y el resto en minúsculas. Por ejemplo, si hacemos una función que busque el número de teléfono de una persona en una base de datos, podríamos llamarla "busca_telefono" o "BuscaTelefono".
  • Una lista de declaraciones de parámetros entre paréntesis. Los parámetros de una función son los valores de entrada (y en ocasiones también de salida). Para la función se comportan exactamente igual que variables, y de hecho cada parámetro se declara igual que una variable. Una lista de parámetros es un conjunto de declaraciones de parámetros separados con comas. Puede tratarse de una lista vacía. En C es preferible usar la forma "func(void)" para listas de parámetros vacías. En C++ este procedimiento se considera obsoleto, se usa simplemente "func()".
Por ejemplo:
int Mayor(int a, int b);
Un prototipo sirve para indicar al compilador los tipos de retorno y los de los parámetros de una función, de modo que compruebe si son del tipo correcto cada vez que se use esta función dentro del programa, o para hacer las conversiones de tipo cuando sea necesario.
En el prototipo, los nombres de los parámetros son opcionales, y si se incluyen suele ser como documentación y ayuda en la interpretación y comprensión del programa. El ejemplo de prototipo anterior sería igualmente válido si se escribiera como:
int Mayor(int, int);
Esto sólo indica que en algún lugar del programa se definirá una función "Mayor" que admite dos parámetros de tipo int y que devolverá un valor de tipoint. No es necesario escribir nombres para los parámetros, ya que el prototipo no los usa. En otro lugar del programa habrá una definición completa de la función.
Normalmente, los prototipos de las funciones se declaran dentro del fichero del programa, o bien se incluyen desde un fichero externo, llamado fichero de cabecera, (para esto se usa la directiva #include, que veremos en el siguiente capítulo).
Ya lo hemos dicho más arriba, pero las funciones son extern por defecto. Esto quiere decir que son accesibles desde cualquier punto del programa, aunque se encuentren en otros ficheros fuente del mismo programa.
En contraposición las funciones declaradas static sólo son accesibles dentro del fichero fuente donde se definen.

Definición de funciones

^
Al igual que hemos visto con las variables, las funciones deben declararse, para lo que usaremos los prototipos, pero también deben definirse.
Una definición contiene además las instrucciones con las que la función realizará suTRABAJO, es decir, su código.
La sintaxis de una definición de función es:
[extern|static] <tipo_valor_retorno> [modificadores] <identificador>(<lista_parámetros>)
{
   [sentencias]
}
Como vemos, la sintaxis es idéntica a la del prototipo, salvo que se elimina el punto y coma final, y se añade el cuerpo de función que representa el código que será ejecutado cuando se llame a la función. El cuerpo de la función se encierra entre llaves "{}".
La definición de la función se hace más adelante o más abajo, según se mire, es decir, se hace después que el prototipo. Lo habitual es hacerlo después de la función main.
Una función muy especial es la función main, de la que ya hablamos en el capítulo primero. Se trata de la función de entrada, y debe existir siempre, ya será la que tome el control cuando se ejecute el programa. Los programas Windows usan la función WinMain como función de entrada, aunque en realidad esta función contiene en su interior la definición de una función main, pero todo esto se explica en otro lugar.
Existen reglas para el uso de los valores de retorno y de los parámetros de la función main, pero de momento la usaremos como int main() o intmain(void), con un entero como valor de retorno y sin parámetros de entrada. El valor de retorno indicará si el programa ha terminado sin novedad ni errores retornando cero, cualquier otro valor de retorno indicará un código de error.

Estructura de un programa C++

^
La estructura de un programa en C o C++ quedaría así:
[directivas del pre-procesador: includes y defines]
[declaración de variables globales]
[prototipos de funciones]
[declaraciones de clases]
función main 
[definiciones de funciones]
[definiciones de clases]
También se puede omitir el prototipo si se hace la definición antes de cualquier llamada a la función, es decir, en la zona de declaración de prototipos. Esto se puede hacer siempre, sin embargo no es muy recomendable como veremos a lo largo del curso.
Para no dejar las cosas "a medias", podemos ver una posible definición de la función "Mayor", que podría ser la siguiente:
int Mayor(int a, int b)
{
   if(a > b) return a; else return b;
}

Estructuras más complejas

Los programas complejos se escriben normalmente usando varios ficheros fuente. Estos ficheros se compilan separadamente y se enlazan todos juntos. Esto es una gran ventaja durante el desarrollo y depuración de grandes programas, ya que las modificaciones en un fichero fuente sólo nos obligarán a compilar ese fichero fuente, y no el resto, con el consiguiente ahorro de tiempo.
La definición de las funciones y clases puede hacerse dentro de los ficheros fuente o también pueden enlazarse desde bibliotecas compiladas previamente.
En C++ es obligatorio el uso funciones prototipo, y aunque en C no lo es, resulta altamente recomendable.

martes, 19 de mayo de 2015

EVALUACIÓN PERMANENTE 4


Intensidad de corriente


Intensidad de Corriente eléctrica. La corriente eléctrica es la circulación de cargas eléctricas en un circuito eléctrico.

La intensidad de corriente eléctrica(I) es la cantidad de electricidad o carga eléctrica(Q) que circula por un circuito en la unidad de tiempo(t). Para denominar la Intensidad se utiliza la letra I y su unidad es el Amperio(A).

Ejemplo: I=10A


La intensidad de corriente eléctrica viene dada por la siguiente fórmula:

                                                           



Donde:

I: Intensidad expresada en Amperios (A)

Q: Carga eléctrica expresada en Culombios (C)

t: Tiempo expresado en segundos (seg.)

Habitualmente en vez de llamarla intensidad de corriente eléctrica, se utilizan indistintamente los términos: intensidad o corriente.


resistencia equivalente

Asociación en serie:  Se denomina resistencia equivalente de una asociación respecto de dos puntos A y B, a aquella que conectada a la misma diferencia de potencial, UAB, demanda la misma intensidadI (ver figura 4). Esto significa que ante las mismas condiciones, la asociación y su resistencia equivalente disipan la misma potencia.
Dos o más resistencias se encuentran conectadas en serie cuando al aplicar al conjunto una diferencia de potencial, todas ellas son recorridas por la misma corriente.
Para determinar la resistencia equivalente de una asociación serie imaginaremos que ambas, figuras 4a) y 4c), están conectadas a la misma diferencia de potencial, UAB. Si aplicamos la segunda ley de Kirchhoff a la asociación en serie tendremos: 

U_{AB} = U_1 + U_2 +...+ U_n \,
Aplicando la ley de Ohm:
U_{AB} = IR_1 + IR_2 +...+ IR_n = I(R_1 + R_2 +...+ R_n) \,
En la resistencia equivalente:
U_{AB} = IR_{AB} \,
Finalmente, igualando ambas ecuaciones se obtiene que:
IR_{AB} = I(R_1 + R_2 +...+ R_n) \,
Y eliminando la intensidad:
R_{AB} = R_1 + R_2 +...+ R_n = \sum_{k=1}^n R_k

Por lo tanto, la resistencia equivalente a n resistencias montadas en serie es igual a la sumatoria de dichas resistencias.

Asociación en paralelo

Dos o más resistencias se encuentran en paralelo cuando tienen dos terminales comunes de modo que al aplicar al conjunto una diferencia de potencial, UAB, todas las resistencias tienen la misma caída de tensión, UAB.
Para determinar la resistencia equivalente de una asociación en paralelo imaginaremos que ambas, figuras 4b) y 4c), están conectadas a la misma diferencia de potencial mencionada, UAB, lo que originará una misma demanda de corriente eléctrica, I. Esta corriente se repartirá en la asociación por cada una de sus resistencias de acuerdo con la primera ley de Kirchhoff:
{I} = {I_1} + {I_2} + ... + {I_n} \,
Aplicando la ley de Ohm:
{I} = {U_{AB} \over R_1} + {U_{AB} \over R_2} + ... + {U_{AB} \over R_n} = U_{AB}\left({1 \over R_1} + {1 \over R_2} + ... + {1 \over R_n}\right) \,
En la resistencia equivalente se cumple:
I=U_{AB}/R_{AB} \,
Igualando ambas ecuaciones y eliminando la tensión UAB:
{1 \over R_{AB}} = {1 \over R_1} + {1 \over R_2} + ... + {1 \over R_n}
De donde:
R_{AB} = {1 \over \sum_{k=1}^n {1 \over R_k} }
Por lo que la resistencia equivalente de una asociación en paralelo es igual a la inversa de la suma de las inversas de cada una de las resistencias.
Existen dos casos particulares que suelen darse en una asociación en paralelo:
1. Dos resistencias: en este caso se puede comprobar que la resistencia equivalente es igual al producto dividido por la suma de sus valores, esto es:
R_{AB} = {R_1R_2 \over R_1 + R_2} \,
2. k resistencias iguales: su equivalente resulta ser:R_{AB} = {R \over k} \,

Asociación mixta


 Asociaciones mixtas de cuatro resistencias: a) Serie de paralelos, b) Paralelo de series y c) Ejemplo de una de las otras posibles conexiones.
En una asociación mixta podemos encontrarnos conjuntos de resistencias en serie con conjuntos de resistencias en paralelo. En la figura 5 pueden observarse tres ejemplos de asociaciones mixtas con cuatro resistencias.
A veces una asociación mixta es necesaria ponerla en modo texto. Para ello se utilizan los símbolos "+" y "//" para designar las asociaciones serie y paralelo respectivamente. Así con (R1 + R2) se indica que R1 y R2 están en serie mientras que con (R1//R2) que están en paralelo. De acuerdo con ello, las asociaciones de la figura 5 se pondrían del siguiente modo:
a) (R1//R2)+(R3//R4)
b) (R1+R3)//(R2+R4)
c) ((R1+R2)//R3)+R4
Para determinar la resistencia equivalente de una asociación mixta se van simplificando las resistencias que están en serie y las que están en paralelo de modo que el conjunto vaya resultando cada vez más sencillo, hasta terminar con un conjunto en serie o en paralelo. Como ejemplo se determinarán las resistencias equivalentes de cada una de las asociaciones de la figura 5:
a)
R1//R2 = R1//2
R3//R4 = R3//4
RAB = R1//2 + R3//4
b)
R1+R3 = R1+3
R2+R4 = R2+4
RAB = R1+3//R2+4
c)
R1+R2 = R1+2
R1+2//R3 = R1+2//3
RAB = R1+2//3 + R4
Desarrollando se obtiene:
a)
R_{AB}={R1 \cdot R2 \over R1+R2}+{R3 \cdot R4 \over R3+R4}
b)
R_{AB}={(R1+R3) \cdot (R2+R4) \over (R1+R3)+(R2+R4)}
c)
R_{AB}={(R1+R2) \cdot R3 \over (R1+R2)+R3} + R4

Asociaciones estrella y triángulo:

Teorema de Kennelly

Pueden observarse respectivamente las asociaciones estrella y triángulo, también llamadas {T} y \pi o delta respectivamente. Este tipo de asociaciones son comunes en las cargastrifásicas. Las ecuaciones de equivalencia entre ambas asociaciones vienen dadas por el teorema de Kennelly:
El valor de cada una de las resistencias en estrella es igual al cociente del producto de las dos resistencias en triángulo adyacentes al mismo terminal entre la suma de las tres resistencias en triángulo.
RA = {R1 \cdot R3 \over {R1 + R2 + R3}} \,
RB = {R1 \cdot R2 \over {R1 + R2 + R3}} \,
RC = {R2 \cdot R3 \over {R1 + R2 + R3}} \,
Resistencias en triángulo en función de las resistencias en estrella (transformación de estrella a triángulo)
El valor de cada una de las resistencias en triángulo es igual la suma de las dos resistencias en estrella adyacentes a los mismos terminales más el cociente del producto de esas dos resistencias entre la otra resistencia.
R1 = {RA + RB + {RA \cdot RB \over {RC}}} \,
R2 = {RB + RC + {RB \cdot RC \over {RA}}} \,
R3 = {RA + RC + {RA \cdot RC \over {RB}}} \,

Asociación puente


Figura 7. Asociación puente.
Si en una asociación paralelo de series como la mostrada en la figura 5b se conecta una resistencia que una las dos ramas en paralelo, se obtiene una asociación puente como la mostrada en la figura 7.
La determinación de la resistencia equivalente de este tipo de asociación tiene sólo interés pedagógico. Para ello se sustituye bien una de las configuraciones en triángulo de la asociación, la R1-R2-R5 o la R3-R4-R5 por su equivalente en estrella, bien una de las configuraciones en estrella, la R1-R3-R5 o la R2-R4-R5 por su equivalente en triángulo. En ambos casos se consigue transformar el conjunto en una asociación mixta de cálculo sencillo. Otro método consiste en aplicar una fem (E) a la asociación y obtener su resistencia equivalente como relación de dicha fem y la corriente total demandada (E/I).
El interés de este tipo de asociación está en el caso en el que por la resistencia central, R5, no circula corriente o R4, en función de las otras tres. En ello se basan los puentes de Wheatstone y de hilo para la medida de resistencias con precisión.



Potencia:


Una resistencia disipa en calor una cantidad de potencia cuadráticamente proporcional a la intensidad que la atraviesa y a la caída de tensión que aparece en sus bornes.
Comúnmente, la potencia disipada por una resistencia, así como la potencia disipada por cualquier otro dispositivo resistivo, se puede hallar mediante:
P = V \cdot I \,\!
A veces es más cómodo usar la ley de Joule para el cálculo de la potencia disipada, que es:
P = R \cdot I^2 \,\! o también P = {V^2 \over R} \,\!
Observando las dimensiones del cuerpo de la resistencia, las características de conductividad de calor del material que la forma y que la recubre, y el ambiente en el cual está pensado que opere, el fabricante calcula la potencia que es capaz de disipar cada resistencia como componente discreto, sin que el aumento de temperatura provoque su destrucción. Esta temperatura de fallo puede ser muy distinta según los materiales que se estén usando. Esto es, una resistencia de 2 W formada por un material que no soporte mucha temperatura, estará casi fría (y será grande); pero formada por un material metálico, con recubrimiento cerámico, podría alcanzar altas temperaturas (y podrá ser mucho más pequeña).
El fabricante dará como dato el valor en vatios que puede disipar cada resistencia en cuestión. Este valor puede estar escrito en el cuerpo del componente o se tiene que deducir de comparar su tamaño con los tamaños estándar y su respectivas potencias. El tamaño de las resistencias comunes, cuerpo cilíndrico con 2 terminales, que aparecen en los aparatos eléctricos domésticos suelen ser de 1/4 W, existiendo otros valores de potencias de comerciales de ½ W, 1 W, 2 W, etc.

Pseudocodigo: