TÉCNICAS DE PROGRAMACIÓN Lenguaje C - 2

Slides:



Advertisements
Presentaciones similares
Curso de java básico (scjp)
Advertisements

ESTRUCTURAS DE CONTROL
DATSI, FI, UPM José M. Peña Programación en C DATSI, FI, UPM José M. Peña Programación en C.
PROGRAMACIÓN EN C.
Inicio Índice Siguiente Anterior Final Dudas CAPITULO 3 CONTROL DE FLUJO Las instrucciones de control de un lenguaje especifico es el orden en el que se.
PHP-MYSQL OPERADORES EN PHP
Repaso para la construcción del intérprete 2012
Fundamentos de la Programación Estructurada
Programación I Teoría I
Tema 2: Lenguaje PHP básico
Introducción al Lenguaje C (ANSI)
UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO
ALGORÍTMICA Dpto. Ingeniería de Sistemas y Automática
3. INTRODUCCIÓN A LA PROGRAMACIÓN
ESTRUCTURAS DE SECUENCIA
Una breve introducción
Ingeniero Anyelo Quintero
La estructura básica de los programas en java, algo a tener en cuenta y que debemos recordar siempre es el archivo debe llevar el nombre de la clase con.
Funciones en lenguaje C

Tipos de Datos Básicos 1.
Al término de la clase, el alumno reconoce las ventajas de usar JAVASCRIPT para un proyecto web.
Lenguaje C.
LENGUAJE “C” Programación.
Semana 5 Subprogramas..
Características de “C”
Características de “C” Y Esta conformado por un Ambiente Integrado. Y Es un Lenguaje de Nivel medio. Y Es un compilador. YContiene un conjunto de palabras.
Unidad III Elementos del lenguaje C++
Tema 2: Los tipos de datos
Capítulo 1 “Elementos de Programación”
Informática Ingeniería en Electrónica y Automática Industrial
Conversión cadena a número
CAPITULO 1 - INTRODUCCIÓN Comenzaremos con una rápida introducción al lenguaje C. Mostraremos algunos elementos esenciales del lenguaje en programas reales,
Tipo de Datos Básicos.
© AutoresV1.1 Informática Ingeniería en Electrónica y Automática Industrial Datos en lenguaje C.
El lenguaje de programación C - Identificadores y variables – Isidro González Caballero ( Introducción.
Programación en Lenguaje C
Informática Ingeniería en Electrónica y Automática Industrial
El Lenguaje C++. Creación de programas simples de C++ Builder como ejercicios en C++. Los elementos de control fundamentales en C++, incluyendo operadores.
Resumen Fundamentos de Programación/ Programación I
EXPRESIONES Y SENTENCIAS
Programación en C para electrónicos
TÉCNICAS DE PROGRAMACIÓN Lenguaje C - 2
Programación orientada a objetos. El método main es el comportamiento por el cual comienzan todos los programas en Java, de la misma forma en la que C,
Unidad 1: FUNDAMENTOS DE COMPUTACIÓN Y PSEUDOLENGUAJE
Elementos básicos del lenguaje
TÉCNICAS DE PROGRAMACIÓN Lenguaje C
TÉCNICAS DE PROGRAMACIÓN Lenguaje C - 2
PROGRAMACIÓN MULTIMEDIA
FUNDAMENTOS DE PROGRAMACIÓN
Términos algoritmo diseñar algoritmo implementar algoritmo
Estructura de un programa C
CARACTERÍSTICAS Es un lenguaje de programación estructurado de propósito general. Está estrechamente asociado al sistema operativo UNIX, ya que el propio.
PRINCIPIOS DE PROGRAMACIÓN

1 TÉCNICAS DE PROGRAMACIÓN Lenguaje C Tercera Clase (Segunda de C)
Presente un cuestionario con los aspectos mas importantes sobre los
1.  En el Lenguaje C, los nombres usados para referirse a las variables, las constantes, las funciones y otros objetos definidos por el usuario se conocen.
Fundamentos de Programación
Práctica Profesional PHP.
Estructuras de Decisión
Lic. Carla Aguirre Montalvo
CLASE 10. AGENDA 1 Repaso 2 Operadores 3 Directivas 14 Entrada y Salida de Datos.
Lenguaje de programación c
EL TIPO DE DATO LOGICO y constantes.
Informática Ingeniería en Electrónica y Automática Industrial
PROGRAMACIÓN Grupo de Modelamiento de Sistemas
FUNDAMENTOS DE PROGRAMACIÓN VARIABLES, CONSTANTES Y TIPOS DE DATOS EN C.
Programación en Java Introducción a Java. Reseña histórica Surge en 1991 por Sun Microsystems Desarrollado para electrodomésticos Se buscaba un código.
Transcripción de la presentación:

TÉCNICAS DE PROGRAMACIÓN Lenguaje C - 2 Daniel Finol

Escriba un programa que copie su entrada a la salida, reemplazando cada secuencia de uno o más espacios en blanco por un solo espacio.

Escriba una programa que copie la entrada a la salida pero reemplazando cada tabulador por \t, cada backspace por \b, y cada barra por \\.

Escriba un programa que imprima su entrada una palabra por línea.

Arreglos Un arreglo es un conjunto numerado (secuencia) de variables de un mismo tipo. int edades[33]; /*es un arreglo de treinta y tres int’s*/ edades[0] /*este es el primer elemento*/ edades[32] /*este es el último*/ Cada elemento puede usarse exactamente igual que si fuera una variable del tipo indicado. Ej: edades[32] = edades[31] + 2*edades[30];

Arreglos: conteo de dígitos, espacios y otros El siguiente programa cuenta el número de veces que aparece cada dígito decimal, carácter de espaciado (espacio, tabulador y nueva línea), y otros caracteres.

Arreglos: ¿Qué hace este programa? #include <stdio.h> main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); }

Arreglos: conteo de dígitos, espacios y otros #include <stdio.h> main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); } Los caracteres de los dígitos decimales tienen códigos contiguos en el formato ASCII y en todos (o casi) los demás

Arreglos: conteo de dígitos, espacios y otros #include <stdio.h> main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); } Los caracteres de los dígitos decimales tienen códigos contiguos en el formato ASCII y en todos (o casi) los demás

Arreglos: conteo de dígitos, espacios y otros #include <stdio.h> main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); }

Funciones Una función es una forma de encapsular algunas operaciones o cómputos de manera que se puedan usar después sin preocuparse de cómo se hacen.

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { ?

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p;

Funciones Las funciones se definen según este esquema: tipo-retorno nombre(declaraciones de parámetros, si existen) { declaraciones de las variables locales instrucciones } Los nombres de los parámetros y de las variables que se declaran dentro de la función son locales de la función: invisibles para las demás funciones; éstas pueden usar variables con el mismo nombre sin que haya conflicto.

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; Tipo de retorno

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; Nombre de la función

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; Parámetros

Declaración de variables locales Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; Declaración de variables locales

Funciones: ejemplo #include <stdio.h> int power(int m, int n); main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n",i,power(2,i),power(-3,i)); return 0; } int power(int base, int n) { int i, p; p = 1; for (i = 1; i <= n; ++i) p = p * base; return p; Retorno: Devuelve el control a la función que llamó. Regresa el valor indicado.

Argumentos: pase por valor. Los argumentos que se pasan a una función se pasan “por valor”: la función recibe una copia de los valores de los argumentos en variables temporales locales. De esta manera las funciones no pueden modificar los valores de las variables originales de la función que llamó. Los cambios sólo tienen efecto en su copia local. Existe una “excepción”: arreglos. Apuntadores.

Argumentos: pase por valor. int power(int base, int n) { int p; for (p = 1; n > 0; --n) p = p * base; return p; }

Arreglos de caracteres Un programa que lee líneas de texto e imprime la más larga tendría esta forma: mientras(hay otra línea) si (es más larga que la más larga hasta entonces) guardarla guardar su longitud imprimir la más larga

#include <stdio.h> #define MAXLINE 1000 int getline(char s[],int lim) { int c, i; for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) s[i] = c; if (c == '\n') { ++i; } s[i] = '\0'; return i; void copy(char to[], char from[]) { int i; i = 0; while ((to[i] = from[i]) != '\0') main() { int len; int max; char line[MAXLINE]; char longest[MAXLINE]; max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); if (max > 0) printf("%s", longest); return 0;

“hello\n” = En C una cadena de caracteres válida es un arreglo tipo char terminado con el carácter nulo ‘\0’ Las funciones de la librería estándar que trabajan con cadenas asumen que esto es así. ‘E’ != “E” ‘\n’ != “\n”

Variables locales vs. externas Las variables que se declaran dentro de main son locales o privadas de ella. Ninguna otra función tienen acceso a la variables privadas de otra función. Las variables locales automáticas de una función comienzan a existir cuando se inicia la función y dejan de existir cuando finaliza. Deben ser inicializadas cada vez que se llama la función. (Si no: basura). Una alternativa: variables externas. Definidas fuera de toda función. Acceso global. Comunicación alternativa entre funciones. Mantienen sus valores. Las variables locales son automáticas por defecto.

Ejemplo de variables externas (Globales). #include <stdio.h> #define MAXLINE 1000 /* maximum input line size */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */ int getline(void) { int c, i; extern char line[]; for (i = 0; i < MAXLINE - 1 && (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { ++i; } line[i] = '\0'; return i; void copy(void) { int i; extern char line[], longest[]; i = 0; while ((longest[i] = line[i]) != '\0') main() { int len; extern int max; extern char longest[]; max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); if (max > 0) /* there was a line */ printf("%s", longest); return 0; Ejemplo de variables externas (Globales).

Definiciones Declaraciones #include <stdio.h> #define MAXLINE 1000 int max; char line[MAXLINE]; char longest[MAXLINE]; int getline(void) { int c, i; extern char line[]; for (i = 0; i < MAXLINE - 1 && (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { ++i; } line[i] = '\0'; return i; void copy(void) { int i; extern char line[], longest[]; i = 0; while ((longest[i] = line[i]) != '\0') main() { int len; extern int max; extern char longest[]; max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); if (max > 0) /* there was a line */ printf("%s", longest); return 0; Definiciones Declaraciones

Innecesarias si están en el mismo archivo. #include <stdio.h> #define MAXLINE 1000 int max; char line[MAXLINE]; char longest[MAXLINE]; int getline(void) { int c, i; extern char line[]; for (i = 0; i < MAXLINE - 1 && (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { ++i; } line[i] = '\0'; return i; void copy(void) { int i; extern char line[], longest[]; i = 0; while ((longest[i] = line[i]) != '\0') main() { int len; extern int max; extern char longest[]; max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); if (max > 0) /* there was a line */ printf("%s", longest); return 0; Innecesarias si están en el mismo archivo.

#include <stdio.h> #define MAXLINE 1000 int max; char line[MAXLINE]; char longest[MAXLINE]; int getline(void) { int c, i; extern char line[]; for (i = 0; i < MAXLINE - 1 && (c=getchar)) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { ++i; } line[i] = '\0'; return i; void copy(void) { int i; extern char line[], longest[]; i = 0; while ((longest[i] = line[i]) != '\0') main() { int len; extern int max; extern char longest[]; max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); if (max > 0) /* there was a line */ printf("%s", longest); return 0; Esta versión es inferior a la anterior: estas funciones son menos generales.

TIPOS OPERADORES Y EXPRESIONES Capítulo 2 de K y R

Nombres de variables y constantes Letras (mayúsculas o minúsculas; A != a). Dígitos decimales. Subrayado (‘_’). Primer carácter: No puede ser dígito. No debe ser ‘_’. Tradición: minúsculas para los nombres de variables. TODO EN MAYÚSCULAS para las constantes simbólicas.

Nombres de variables y constantes Externas: Sólo hay garantía primeros 6 caracteres. No garantiza A != a. No usar palabras claves. Nombres  Documentación.

El tipo de una variable indica: Tipos de variable El tipo de una variable indica: el conjunto de valores que puede tener, las operaciones que se pueden realizar sobre ella. Tipos básicos: char Un byte; guarda un carácter. int Un entero. float Punto flotante; precisión sencilla (single). double Punto flotante; precisión doble.

Tamaños y Modificadores de tipos Modificadores (o calificadores) para int: short int >= 16 bits. long int >= 32 bits. short <= int <= long. int es del tamaño “normal” de los enteros de la máquina. La palabra int puede omitirse de la declaración. Modificadores signed y unsigned: Se aplican a int y char. unsigned: cero o positivo. unsigned char = [0 , 255] signed char = [-128 , 127] (complemento a 2) long double: p. flotante precisión extendida.

Constantes Una constante entera que tenga el sufijo u o U se toma como unsigned. Una constante entera es long si: No cabe en un int. Está terminada por L o l (ele). Una constante es de punto flotante si: Contiene un punto decimal: 1.234. Está en notación científica: 1e-2. Una constante de punto flotante se toma como double excepto: Si termina en f o F; se toma como float. Si termina en l (ele) o L; se toma como long double.

Constantes Constantes de carácter: 'A', '\0'. Expresiones constantes. Se calculan en tiempo de compilación. Ej. #define MAXLINE 1000 char line[MAXLINE+1]; "Constante de cadena", "". Las comillas no forman parte de la cadena, sólo la delimitan. Una cadena es un arreglo de caracteres. La representación interna de una constante de cadena tiene un carácter nulo al final. El espacio de almacenamiento requerido es uno más que el número de caracteres entre comillas.

Longitud de una cadena. Para saber la longitud de una cadena hay que recorrerla (leerla) toda: int strlen(char s[]) { int i; i = 0; while (s[i] != '\0') ++i; return i; } strlen está en <string.h> 'x' != "x"; 'x' es un entero pequeño. "x" es un arreglo de dos caracteres.

Secuencias de escape \a alert (bell) character \\ backslash \b  \\   backslash  \b   backspace  \?  question mark  \f   formfeed   \'  single quote  \n   newline  \"   double quote  \r   carriage return  \ooo   octal number  \t   horizontal tab  \xhh   hexadecimal number   \v   vertical tab

Enumeraciones enum Crea una lista de constantes auto enumeradas: enum booleana {FALSO, VERDAD}; enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t', NEWLINE = '\n', VTAB = '\v', RETURN = '\r' }; enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; Se pueden declarar variables de tipo enum pero el compilador no chequea qué se le asigna. Serviría más como documentación.

Declaraciones Una declaración especifica un tipo de dato seguido de una o más variables de ese tipo. Si hay más de una variable, estas se separan por comas. Termina en punto y coma. Una variable puede ser inicializada en su declaración: int i = 0; Si no es automática: se inicializa una sola vez al (antes del) inicio del programa. se debe inicializar con una expresión constante.

Declaraciones Si es automática: se inicializa cada vez que se entra al bloque donde se encuentra. puede ser inicializada con cualquier expresión. si no es inicializada contiene valores indefinidos: basura. El calificador const puede aplicarse a la declaración de una variable para especificar que su valor no será cambiado: const double e = 2.71828182845905; const char msg[] = "warning: ";

Operadores aritméticos Operadores aritméticos binarios: +, -, *, / y %. La división entera trunca. x % y es el residuo de x entre y. El módulo es cero cuando x es múltiplo de y. Ej: if((year % 4 == 0 && year % 100 != 0) || year % 400==0) printf("%d es año bisiesto\n", year); else printf("%d no es bisiesto\n", year); Si los operandos son negativos no confiar en: Dirección de truncamiento de /. Signo del resultado de %.

Operadores relacionales y lógicos > < <= >= tienen menor precedencia que los aritméticos. i < lim – 1 se interpreta como i < (lim – 1). Operadores de igualdad: == != Operadores lógicos: && || && tiene mayor precedencia que ||. Ambos son evaluados de izquierda a derecha. La evaluación se detiene tan pronto se conozca el resultado (verdadero o falso).

Operadores lógicos for(i=0; i < lim-1 && (c=getchar()) != '\n' && c != EOF; ++i) s[i] = c; Tienen menor precedencia que los operadores relacionales. Verificar si hay espacio para guardar el carácter antes de leerlo. Leerlo antes de probar si es EOF o nueva línea. Precedencia de != es mayor que la de asignación; se necesitan paréntesis en (c=getchar()) != '\n'

Operador unario de negación ! El valor numérico de una expresión lógica y relacional es 1 si es verdadera y 0 de ser falsa. Operador unario de negación ! if(!valid) es equivalente a if(valid == 0)

Conversiones de tipo Si un operador tiene operandos de tipos distintos, éstos se convierten a un tipo común siguiendo ciertas reglas. Las únicas conversiones automáticas son las que convierten un operando "pequeño" o "angosto" o uno más "grande" o "amplio" sin pérdida de información. Ej.: de entero a punto flotante en f + i. Operaciones que pueden perder información no son ilegales (no producen error).

Conversión de una cadena Un char es un entero pequeño, de modo que se puede usar en expresiones aritméticas. atoi convierte una cadena de dígitos a su equivalente en un valor entero: int atoi(char s[]) { int i, n; n = 0; for(i = 0; s[i] >= '0' && s[i] <= '9'; ++i) n = 10 * n + (s[i] - '0'); return n; }

char a int El estándar no especifica si las variables char tienen signo o no. Cuando una variable char se convierte a int ¿es posible que produzca un número negativo? Respuesta: depende de la implantación. Portabilidad: se debe especificar unsigned o signed si se van a guardar datos que no son caracteres en una variable char.

Conversiones automáticas En una operación binaria (que no sea de asignación): se promueve la variable más "pequeña" al tipo de la más grande. los char y short se promueven a int. En una asignación se transforma el valor de la derecha al tipo de la variable de la izquierda. int i; char c; ... i = c; c = i; int i; char c; ... c = i; i = c;

casting Se puede forzar explícitamente la conversión de tipo de cualquier expresión con el operador de cast: (nuevo-tipo) expresión Si usan funciones que no han sido declaradas se realiza una conversión por defecto de los argumentos que no necesariamente corresponde a los tipos de los parámetros de la función. Esto puede producir errores. Ej. sqrt.

casting – Números aleatorios unsigned long int next = 1; int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } void srand(unsigned int seed) next = seed;

Operadores de incremento y decremento ++ y -- incrementa y disminuye, respectivamente, en 1 (uno) la variable a la que se aplique. Prefijo (++x o --x): modifican x antes de su uso. Posfijo (x++ o x--): modifican x luego de su uso. n = 5; x = n++; n = 5; x = ++n; if (c == '\n') nl++; if (c == '\n') ++nl;

Operador de incremento -- squeez void squeeze(char s[], int c) { int i, j; for (i = j = 0; s[i] != '\0'; i++) if (s[i] != c) s[j++] = s[i]; s[j] = '\0'; } ____________________________________________________ if (s[i] != c) { s[j] = s[i]; j++;

Operador de incremento - ¿Qué hace la función? void f(char s[], char t[]) { int i, j; i = j = 0; while (s[i] != '\0') i++; while ((s[i++] = t[j++]) != '\0') ; }

Operador de incremento - Concatenación void strcat(char s[], char t[]) { int i, j; i = j = 0; while (s[i] != '\0') i++; while ((s[i++] = t[j++]) != '\0') ; }

Manejo de bits Los operadores para manejo de bits sólo pueden aplicarse a enteros (char, short, int y long): & Y (AND) de bits | O (OR) inclusivo de bits ^ O exclusivo (XOR) de bits <<   desplazamiento (shift) a la izquierda >> desplazamiento (shift) a la derecha ~ complemento a uno (unario)

Operadores de bits El operador Y de bits (&) sirve para enmascarar bits: n = n & 0177 El operador O inclusivo (|) puede encender bits: n = n | SET_ON El operador O exclusivo (^) pone uno en cada posición donde sus operandos tienen bits distintos y cero donde no. 1 & 2 == ? 1 && 2 == ?

Operadores de bits El operador Y de bits (&) sirve para enmascarar bits: n = n & 0177 El operador O inclusivo (|) puede encender bits: n = n | SET_ON El operador O exclusivo (^) pone uno en cada posición donde sus operandos tienen bits distintos y cero donde no. 1 & 2 == 0 1 && 2 == 1

Operadores de bits << desplazamiento a la derecha. llena con ceros. x << n == x*2n. >> desplazamiento a la izquierda. unsigned >> llena con ceros. signed >> depende de la implantación. ~ complemento x = x & ~077; independiente del tamaño de x

Operadores de bits -- getbits unsigned getbits(unsigned x, int p, int n) { return (x >> (p+1-n)) & ~(~0 << n); }

Operadores de asignación Las operaciones de asignación en las que el operando de la izquierda se repite inmediatamente a la derecha del = pueden abreviarse: i = i + 2  i += 2 i += 2 (“incrementar i en 2”) se lee más fácil que: i = i + 2 (“tomar i sumarle 2 y poner el resultado en i”)

Operadores de asignación Hay operadores de asignación para: + - * / % << >> & ^ | expresión1 op= expresión2 es equivalente a expresión1 = (expresión1)op (expresión2) excepto que expresión1 se evalúa una sola vez x *= y + 1 es eq. a x = x * (y + 1)

Operadores de asignación – Conteo de bits int bitcount(unsigned x) { int b; for (b = 0; x != 0; x >>= 1) if (x & 01) b++; return b; } (x es sin signo para garantizar que no haya extensión de signo) ________________________________________________ yyval[yypv[p3+p4] + yypv[p1]] += 2

Expresiones condicionales ?: expr1 ? expr2 : expr3 z = (a > b) ? a : b; Tipo: si f es float y n int: (n > 0) ? f : n es float. Ej.: for (i = 0; i < n; i++) printf("%6d%c",a[i], (i%10==9 || i==n-1) ? '\n' : ' '); ________________________________________________________ printf("Hay %d elemento%s.\n", n, n==1 ? "" : "s");

Precedencia Operadores Asociatividad () [] -> . izquierda a derecha ! ~ ++ -- + - * (type) sizeof derecha a izquierda * / % + - <<  >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= , Precedencia if(x & MASK == 0)

Precedencia Para la mayoría de los operadores no está definido el orden de evaluación de sus operandos. Excepciones: (&&, ||, ?:, y ',' ) x = f() + g() El orden de evaluación de los argumentos tampoco está definido: /* MALO */ printf("%d %d\n", ++n, power(2, n));

Efectos colaterales ≈ Daños colaterales Las llamadas a funciones, asignaciones anidadas y operadores de incremento y decremento producen "efectos colaterales“: Alguna variable se modifica como efecto de la evaluación de una expresión. s[i] = i++; ¿? Escribir código que dependa del orden de evaluación es una mala práctica. (No es portable)

CONTROL DE FLUJO Capítulo 3 de K y R

Control de flujo Las proposiciones de control de flujo señalan el orden en el que se ejecutan las instrucciones. Una expresión se convierte en instrucción (proposición) cuando va seguida de punto y coma.

Decisiones: if-else Sintaxis formal: if (expresión) instrucción1 else La parte del else es opcional. if (expresión) es eq. if (expresión != 0)

Ambigüedad if (n > 0) if (a > b) z = a; else z = b;

Ambigüedad if (n > 0) if (a > b) z = a; else z = b;

Desambiguación if (n > 0) { if (a > b) z = a; } else z = b;

Ejemplo if (n > 0) for (i = 0; i < n; i++) if (s[i] > 0) { printf("..."); return i; } else /* MAL */ printf("error -- n es negativa\n");

Decisiones múltiples: else-if if (expression) statement else if (expression) else Cuando alguna expresión es cierta la instrucción correspondiente se ejecuta y termina la cadena. Caso "ninguno de los anteriores" o caso por omisión. (Opcional)

Búsqueda Si tenemos una secuencia de cartas ordenadas, bocabajo, y sólo podemos destapar una a la vez ¿cuál es la manera más rápida de encontrar una carta con un valor específico?

else-if: Búsqueda binaria int binsearch(int x, int v[], int n) { int low, high, mid; low = 0; high = n - 1; while (low <= high) { mid = (low+high)/2; if (x < v[mid]) high = mid - 1; else if (x > v[mid]) low = mid + 1; else /* se encontró */ return mid; } return -1; /* no se encontró */

Decisiones múltiples: switch switch (expression) { case const-expr: statements default: statements }

switch: Ejemplo main() { int c, i, nwhite, nother, ndigit[10]; for (i = 0; i < 10; i++) ndigit[i] = 0; while ((c = getchar()) != EOF) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ndigit[c-'0']++; break; case ' ': case '\n': case '\t': nwhite++; default: nother++; } printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); return 0;

No olvidar breaks, incluso el último. switch: Ejemplo main() { int c, i, nwhite, nother, ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; i++) ndigit[i] = 0; while ((c = getchar()) != EOF) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ndigit[c-'0']++; break; case ' ': case '\n': case '\t': nwhite++; default: nother++; } printf("digits ="); printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); return 0; No olvidar breaks, incluso el último.

Ciclos: while y for while (expression) statement expr1; while (expr2) { statement expr3; } for (expr1; expr2; expr3) statement

atoi 2 #include <ctype.h> int atoi(char s[]) { int i, n, sign; for (i = 0; isspace(s[i]); i++) ; sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (n = 0; isdigit(s[i]); i++) n = 10 * n + (s[i] - '0'); return sign * n; }

Ordenación ¿Cómo sería un algoritmo simple para ordenar un arreglo?

shellsort void shellsort(int v[], int n) { int gap, i, j, temp; for (gap = n/2; gap > 0; gap /= 2) for (i = gap; i < n; i++) for (j=i-gap; j>=0 && v[j]>v[j+gap]; j-=gap) { temp = v[j]; v[j] = v[j+gap]; v[j+gap] = temp; }

Operador coma (,) expr1 , expr2 : Evalúa expr1, luego expr2 y la expresión completa tiene el tipo y valor de expr2. Se usa sobre todo en el for. Las comas que se usan para separar los argumentos de una función o las variables de una declaración no son operadores coma: no garantizan el orden de evaluación.

Ejemplo coma: reverse #include <string.h> void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; }

Ejemplo coma: reverse #include <string.h> void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s)-1; i < j; i++, j--) c = s[i], s[i] = s[j], s[j] = c; }

Ciclo do-while do statement while (expression);

do-while: itoa void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* guardar signo */ n = -n; /* hacer n positiva */ i = 0; do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); }

break y continue break: Hace que el ciclo o switch más interno termine inmediatamente. continue: Hace que se interrumpa la iteración actual y se inicie inmediatamente la siguiente: en un while y en un do se pasa a la parte de prueba. en un for se pasa a la parte de incremento.

Ejemplo break: trim int trim(char s[]) { int n; for (n = strlen(s)-1; n >= 0; n--) if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n') break; s[n+1] = '\0'; return n; }

Ejemplo continue for (i = 0; i < n; i++) { if (a[i] < 0) ... /* do positive elements */ }

La instrucción prohibida: goto La instrucción goto (ir a) ocasiona un salto hacia otro punto de la función señalado con una etiqueta. Ej: for ( ... ) for ( ... ) { ... if (desastre) goto error; } error: /* arreglar el desastre */ Siempre se puede escribir sin goto. Opiniones.

FUNCIONES Y ESTRUCTURA DEL PROGRAMA CAPÍTULO 4 DE KyR

Ejemplo Imprimir las líneas de la entrada que contengan un patrón dado: while (haya otra línea) if (la línea contiene el patrón) imprimirla haya otra línea: getline. imprimirla: printf. Falta: la línea contiene el patrón.

Ejemplo #include <stdio.h> #define MAXLINE 1000 int getline(char line[], int max) int strindex(char source[], char searchfor[]); char pattern[] = "patrón"; main() { char line[MAXLINE]; int found = 0; while (getline(line, MAXLINE) > 0) if (strindex(line, pattern) >= 0) { printf("%s", line); found++; } return found;

getline(char, int) int getline(char s[], int lim) { int c, i; i = 0; while(--lim > 0 && (c=getchar()) !=EOF && c!='\n') s[i++] = c; if (c == '\n') s[i] = '\0'; return i; }

strindex int strindex(char s[], char t[]) { int i, j, k; for (i = 0; s[i] != '\0'; i++) { for(j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++,k++) ; if (k > 0 && t[k] == '\0') return i; } return -1;

Forma de una función tipo-de-retorno nombre(declaraciones de argumentos) { declaraciones e instrucciones } Una función con un tipo de retorno distinto de void debe retornar algún valor Si la ejecución llega al final de la función y la última instrucción no es un return el valor de la función es "basura".

Funciones El programa fuente puede dividirse en varios archivos, mientras las funciones no se dividan. cc main.c getline.c strindex.c cc main.c getline.o strindex.o

Arreglos Bidimensionales int a[10][5];