Herramientas de usuario

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
esenciales_de_c [2024/09/23 22:48] – [The C Language] peronesenciales_de_c [2026/04/21 16:06] (actual) – editor externo 127.0.0.1
Línea 3: Línea 3:
 This is document #101, "Essential C", in the Stanford CS Education Library. This and other educational materials are available for free at http://cslibrary.stanford.edu/. This article is free to be used, reproduced, excerpted, retransmitted, or sold so long as this notice is clearly reproduced at its beginning. This is document #101, "Essential C", in the Stanford CS Education Library. This and other educational materials are available for free at http://cslibrary.stanford.edu/. This article is free to be used, reproduced, excerpted, retransmitted, or sold so long as this notice is clearly reproduced at its beginning.
  
-======C Esencial ======+======Apuntes Esenciales de C ======
  
 Este documento del Depto de Ciencias del Cómputo de la Universidad de Stanford intenta resumir las funcionalidades y características básicas del [[Lenguaje C]]. Se abarca de manera resumida, de modo que resulta apropiado como un repaso, o para alguien con cierto conocimiento previo de otro lenguaje de programación. Los temas incluyen variables, tipos de entero, tipos de coma flotante, promoción, truncado, operadores, estructuras de control, (if, while, for), funciones, parámetros de valor, parámetros de referencia, estructuras, punteros, arreglos, el preprocesador, y las funciones de las librerías estándares de C. Este documento del Depto de Ciencias del Cómputo de la Universidad de Stanford intenta resumir las funcionalidades y características básicas del [[Lenguaje C]]. Se abarca de manera resumida, de modo que resulta apropiado como un repaso, o para alguien con cierto conocimiento previo de otro lenguaje de programación. Los temas incluyen variables, tipos de entero, tipos de coma flotante, promoción, truncado, operadores, estructuras de control, (if, while, for), funciones, parámetros de valor, parámetros de referencia, estructuras, punteros, arreglos, el preprocesador, y las funciones de las librerías estándares de C.
Línea 9: Línea 9:
 Consulte su [[http://cslibrary.stanford.edu/101/|versión más reciente]]. Envíe comentarios a su autor [[nick.parlante@cs.stanford.edu|Nick Parlante]].  Consulte su [[http://cslibrary.stanford.edu/101/|versión más reciente]]. Envíe comentarios a su autor [[nick.parlante@cs.stanford.edu|Nick Parlante]]. 
  
-====The Language====+====El lenguaje C====
  
 C es un lenguaje de programación profesional, y como tal fue diseñado para meterse lo menos posible en el camino del programador. Kernighan y Ritchie escribieron la definición original en su libro, //The C Programming Language//, como parte de su investigación en [[AT&T]]. El sistema operativo [[Unix]] y el lenguaje C++ emergieron de los mismos [[laboratorios bell|Laboratorios]]. C es un lenguaje de programación profesional, y como tal fue diseñado para meterse lo menos posible en el camino del programador. Kernighan y Ritchie escribieron la definición original en su libro, //The C Programming Language//, como parte de su investigación en [[AT&T]]. El sistema operativo [[Unix]] y el lenguaje C++ emergieron de los mismos [[laboratorios bell|Laboratorios]].
Línea 34: Línea 34:
 ===Otros Recursos=== ===Otros Recursos===
  
-  * **The C Programming Language**, 2da edición, de Kernighan y Ritchie. Por años, este libro ha sido la biblia para todos los programadores de C, escrito por los diseñadores originales del lenguaje. Las explicaciones son bastante breves, de modo q1ue este libro es mejor como referencia para principiantes.+  * **[[el lenguaje de programacion c|The C Programming Language]]**, 2da edición, de Kernighan y Ritchie. Por años, este libro ha sido la biblia para todos los programadores de C, escrito por los diseñadores originales del lenguaje. Las explicaciones son bastante breves, de modo q1ue este libro es mejor como referencia para principiantes.
  
   * [[http://cslibrary.stanford.edu/102/|Pointers and Memory]] -- Muchos más detalles sobre memoria local, punteros, parámetros de referencia, y memoria heap que el que se encuentra en este artículo, y la memoria es realmente la parte más difícil de C y C++.   * [[http://cslibrary.stanford.edu/102/|Pointers and Memory]] -- Muchos más detalles sobre memoria local, punteros, parámetros de referencia, y memoria heap que el que se encuentra en este artículo, y la memoria es realmente la parte más difícil de C y C++.
Línea 67: Línea 67:
 |''<nowiki>'\012'</nowiki>'' |the character with value 12 in octal, which is decimal 10 | |''<nowiki>'\012'</nowiki>'' |the character with value 12 in octal, which is decimal 10 |
  
-====int Constants ====+====Constantes int ====
  
 Numbers in the source code such as ''234'' default to type ''int''. They may be followed by an ''<nowiki>'L'</nowiki>'' (upper or lower case) to designate that the constant should be a long such as ''42L''. An integer constant can be written with a leading 0x to indicate that it is expressed in hexadecimal -- 0x10 is way of expressing the number 16. Similarly, a constant may be written in octal by preceding it with "0" -- 012 is a way of expressing the number 10. Numbers in the source code such as ''234'' default to type ''int''. They may be followed by an ''<nowiki>'L'</nowiki>'' (upper or lower case) to designate that the constant should be a long such as ''42L''. An integer constant can be written with a leading 0x to indicate that it is expressed in hexadecimal -- 0x10 is way of expressing the number 16. Similarly, a constant may be written in octal by preceding it with "0" -- 012 is a way of expressing the number 10.
  
-====Type Combination and Promotion====+====Combinación y Promoción de Tipos====
  
 The integral types may be mixed together in arithmetic expressions since they are all basically just integers with variation in their width. For example, ''char'' and ''int'' can be combined in arithmetic expressions such as ''('b' + 5)''. How does the compiler deal with the different widths present in such an expression? In such a case, the compiler "promotes" the smaller type (''char'') to be the same size as the larger type (''int'') before combining the values. Promotions are determined at compile time based purely on the **types** of the values in the expressions. Promotions do not lose information -- they always convert from a type to compatible, larger type to avoid losing information. The integral types may be mixed together in arithmetic expressions since they are all basically just integers with variation in their width. For example, ''char'' and ''int'' can be combined in arithmetic expressions such as ''('b' + 5)''. How does the compiler deal with the different widths present in such an expression? In such a case, the compiler "promotes" the smaller type (''char'') to be the same size as the larger type (''int'') before combining the values. Promotions are determined at compile time based purely on the **types** of the values in the expressions. Promotions do not lose information -- they always convert from a type to compatible, larger type to avoid losing information.
Línea 79: Línea 79:
 I once had a piece of code which tried to compute the number of bytes in a buffer with the expression ''(k * 1024)'' where ''k'' was an ''int'' representing the number of kilobytes I wanted. Unfortunately this was on a machine where int happened to be 16 bits. Since ''k'' and ''1024'' were both ''int'', there was no promotion. For values of ''k >= 32'', the product was too big to fit in the 16 bit int resulting in an overflow. The compiler can do whatever it wants in overflow situations -- typically the high order bits just vanish. One way to fix the code was to rewrite it as ''(k * 1024L)'' -- the ''long'' constant forced the promotion of the ''int''. This was not a fun bug to track down -- the expression sure looked reasonable in the source code. Only stepping past the key line in the debugger showed the overflow problem. "Professional Programmer's Language." This example also demonstrates the way that C only promotes based on the **types** in an expression. The compiler does not consider the values 32 or 1024 to realize that the operation will overflow (in general, the values don't exist until run time anyway). The compiler just looks at the compile time types, ''int'' and ''int'' in this case, and thinks everything is fine. I once had a piece of code which tried to compute the number of bytes in a buffer with the expression ''(k * 1024)'' where ''k'' was an ''int'' representing the number of kilobytes I wanted. Unfortunately this was on a machine where int happened to be 16 bits. Since ''k'' and ''1024'' were both ''int'', there was no promotion. For values of ''k >= 32'', the product was too big to fit in the 16 bit int resulting in an overflow. The compiler can do whatever it wants in overflow situations -- typically the high order bits just vanish. One way to fix the code was to rewrite it as ''(k * 1024L)'' -- the ''long'' constant forced the promotion of the ''int''. This was not a fun bug to track down -- the expression sure looked reasonable in the source code. Only stepping past the key line in the debugger showed the overflow problem. "Professional Programmer's Language." This example also demonstrates the way that C only promotes based on the **types** in an expression. The compiler does not consider the values 32 or 1024 to realize that the operation will overflow (in general, the values don't exist until run time anyway). The compiler just looks at the compile time types, ''int'' and ''int'' in this case, and thinks everything is fine.
  
-====Floating point Types====+====Tipos de coma flotante====
  
 |''float'' |Single precision floating point number| typical size: 32 bits | |''float'' |Single precision floating point number| typical size: 32 bits |
Línea 91: Línea 91:
 The sum may or may not be 1.0 exactly, and it may vary from one type of machine to another. For this reason, you should never compare floating numbers to eachother for equality (''=='') -- use inequality (''<'') comparisons instead. Realize that a correct C program run on different computers may produce slightly different outputs in the rightmost digits of its floating point computations. The sum may or may not be 1.0 exactly, and it may vary from one type of machine to another. For this reason, you should never compare floating numbers to eachother for equality (''=='') -- use inequality (''<'') comparisons instead. Realize that a correct C program run on different computers may produce slightly different outputs in the rightmost digits of its floating point computations.
  
-====Comments====+====Comentarios====
  
 Comments in C are enclosed by slash/star pairs: ''<nowiki>/* .. comments .. */</nowiki>'' which may cross multiple lines. C++ introduced a form of comment started by two slashes and extending to the end of the line: ''<nowiki>// comment until the line end</nowiki>''. The ''<nowiki>// comment</nowiki>'' form is so handy that many C compilers now also support it, although it is not technically part of the C language.  Comments in C are enclosed by slash/star pairs: ''<nowiki>/* .. comments .. */</nowiki>'' which may cross multiple lines. C++ introduced a form of comment started by two slashes and extending to the end of the line: ''<nowiki>// comment until the line end</nowiki>''. The ''<nowiki>// comment</nowiki>'' form is so handy that many C compilers now also support it, although it is not technically part of the C language. 
Línea 118: Línea 118:
 </code> </code>
  
-==== Assignment Operator = ====+==== Operador de Asignación = ====
  
 The assignment operator is the single equals sign (=). The assignment operator is the single equals sign (=).
Línea 133: Línea 133:
 </code> </code>
  
-====Truncation====+====Truncado====
  
 The opposite of promotion, truncation moves a value from a type to a smaller type. In that case, the compiler just drops the extra bits. It may or may not generate a compile time warning of the loss of information. Assigning from an integer to a smaller integer (e.g.. long to int, or int to char) drops the most significant bits. Assigning from a floating point type to an integer drops the fractional part of the number. The opposite of promotion, truncation moves a value from a type to a smaller type. In that case, the compiler just drops the extra bits. It may or may not generate a compile time warning of the loss of information. Assigning from an integer to a smaller integer (e.g.. long to int, or int to char) drops the most significant bits. Assigning from a floating point type to an integer drops the fractional part of the number.
Línea 161: Línea 161:
 </code> </code>
  
-==== Pitfall -- int vs. float Arithmetic ====+==== Pitfall -- int vs. aritmética float ====
  
 Here's an example of the sort of code where int vs. float arithmetic can cause problems. Suppose the following code is supposed to scale a homework score in the range 0..20 to be in the range 0..100. Here's an example of the sort of code where int vs. float arithmetic can cause problems. Suppose the following code is supposed to scale a homework score in the range 0..20 to be in the range 0..100.
Línea 185: Línea 185:
 </code> </code>
  
-==== No Boolean -- Use int ====+==== Sin booleano -- Use int ====
  
 C does not have a distinct boolean type-- int is used instead. The language treats integer 0 as false and all non-zero values as true. So the statement... C does not have a distinct boolean type-- int is used instead. The language treats integer 0 as false and all non-zero values as true. So the statement...
Línea 197: Línea 197:
 will execute until the variable i takes on the value 10 at which time the expression (i - 10) will become false (i.e. 0). (we'll see the while() statement a bit later) will execute until the variable i takes on the value 10 at which time the expression (i - 10) will become false (i.e. 0). (we'll see the while() statement a bit later)
  
-==== Mathematical Operators ====+==== Operadores Matemáticos ====
  
 C includes the usual binary and unary arithmetic operators. See the appendix for the table C includes the usual binary and unary arithmetic operators. See the appendix for the table
Línea 212: Línea 212:
 |''%'' |Remainder (mod) | |''%'' |Remainder (mod) |
  
-==== Unary Increment Operators: ++ -- ====+==== Operadores de incremento unitario: ++ -- ====
  
 The unary ''++'' and ''--'' operators increment or decrement the value in a variable. There are "pre" and "post" variants for both operators which do slightly different things (explained below) The unary ''++'' and ''--'' operators increment or decrement the value in a variable. There are "pre" and "post" variants for both operators which do slightly different things (explained below)
Línea 231: Línea 231:
 </code> </code>
  
-====Pre and Post Variations==== +====Variaciones Pre Post==== 
  
 The Pre/Post variation has to do with nesting a variable with the increment or decrement operator inside an expression -- should the entire expression represent the value of the variable before or after the change? I never use the operators in this way (see below), but an example looks like... The Pre/Post variation has to do with nesting a variable with the increment or decrement operator inside an expression -- should the entire expression represent the value of the variable before or after the change? I never use the operators in this way (see below), but an example looks like...
Línea 246: Línea 246:
 </code> </code>
  
-==== C Programming Cleverness and Ego Issues ====+=== C Programming Cleverness and Ego Issues ===
  
 Relying on the difference between the pre and post variations of these operators is a classic area of C programmer ego showmanship. The syntax is a little tricky. It makes the code a little shorter. These qualities drive some C programmers to show off how clever they are. C invites this sort of thing since the language has many areas (this is just one example) where the programmer can get a complex effect using a code which is short and dense. Relying on the difference between the pre and post variations of these operators is a classic area of C programmer ego showmanship. The syntax is a little tricky. It makes the code a little shorter. These qualities drive some C programmers to show off how clever they are. C invites this sort of thing since the language has many areas (this is just one example) where the programmer can get a complex effect using a code which is short and dense.
Línea 268: Línea 268:
  
 ====Operadores Relacionales==== ====Operadores Relacionales====
 +
 Estos operan en valores enteros o de coma flotante, y devuelven un valor de boole ''0'' o ''1''. Estos operan en valores enteros o de coma flotante, y devuelven un valor de boole ''0'' o ''1''.
  
Línea 294: Línea 295:
  
  
-====Logical Operators==== +====Operadores Lógicos====
- +
-The value 0 is false, anything else is true. The operators evaluate left to right and stop as soon as the truth or falsity of the expression can be deduced. (Such operators are called "short circuiting") In ANSI C, these are furthermore guaranteed to use 1 to represent true, and not just some random non-zero bit pattern. However, there are many C programs out there which use values other than 1 for true (non-zero pointers for example), so when programming, do not assume that a true boolean is necessarily 1 exactly.+
  
-|''!'' |Boolean not (unary) | +El valor 0 es falso, todos lo demás dan verdadero. Los operadores evalúan de izquierda a derecha y se detienen tan pronto se deduce la falsedad o veracidad de la expresión (se dice que tales operadores "cortocircuitan"). En ANSI C, esto se garantiza aún más usando ''1'' para representar verdad, y no sólo cualquier número no cero o patrón de bits azarosos. Sin embargo, existen muchos programas de C que usan valores distinos a ''1'' para verdad (los punteros no cero por ejemploo), de modo que cuando progrrame, no asuma que el booleano true es necesariamente un ''1'' exacto.
-|''&&'' |Boolean and | +
-|''||'' |Boolean or |+
  
-====Bitwise Operators====+|''!'' |//NOT// de Boole (unitario) | 
 +|''&&'' |//AND// de Boole | 
 +|''||'' |//OR// de Boole |
  
-includes operators to manipulate memory at the bit levelThis is useful for writing low-level hardware or operating system code where the ordinary abstractions of numberscharacterspointersetc... are insufficient -- an increasingly rare need. Bit manipulation code tends to be less "portable"Code is "portable" if with no programmer intervention it compiles and runs correctly on different types of computersThe bitwise operations are typically used with unsigned typesIn particular, the shift operations are guaranteed to shift 0 bits into the newly vacated positions when used on unsigned values.+====Operadores de Bit==== 
 +incluye operadores de bit ("bitwise operators") para manipular la memoria a nivel bit. Estos resultan útiles para escribir hardware de bajo nivel o código de sistema operativoen momentos donde las abstracciones orginarias de númeroscaracterespunteros, etcétera, resultan insuficientes (una necesidad cada vez más rara)El código de manipulación de bit tiende a resultar menos "portable"El código fuente es "portable" si compila y se ejecuta correctamente en diferentes tipos de computadoras sin intervención intermedia del programadorLas operaciones de bit generalmente se usan con tipos sin signoEn particular, cuando se usan en valores sin signo, las operaciones de cambio garantizan a cambiar 0 bits en las posiciones recientemente vacantes.
  
-| ''~'' |Bitwise Negation (unary) – flip to and to throughout +| ''~'' |//Negación// de bit (unitaria) – conmuta de ''0'' a ''1'' y de ''1''en todo lo largo 
-| ''&'' |Bitwise And +| ''&'' |//AND// de bit 
-| ''|'' |Bitwise Or +| ''|'' |//OR// de bit 
-| ''^'' |Bitwise Exclusive Or +| ''^'' |//OR Exclusivo// de bit 
-| ''>>'' |Right Shift by right hand side (RHS) (divide by power of 2) | +| ''>>'' |Cambio de banda por derecha (RHS) (divide por potencia de 2) | 
-| ''<<'' |Left Shift by RHS (multiply by power of 2) |+| ''<<'' |Cambio de banda por izquierda LHS (multiplica por la potencia de 2) |
  
-Do not confuse the Bitwise operators with the logical operatorsThe bitwise connectives are one character wide (''&'', ''|''while the boolean connectives are two characters wide (''&&'', ''||''). The bitwise operators have higher precedence than the boolean operatorsThe compiler will never help you out with a type error if you use ''&'' when you meant ''&&''As far as the type checker is concernedthey are identical-- they both take and produce integers since there is no distinct boolean type.+No confunda los operadores de nivel bit con los operadores lógicosPara evitar confusiones, recuerde que las conectivas a nivel bit tienen un único carácter (''&'', ''|''), mientras que las conectivas de Boole tienen dos caracteres de ancho (''&&'', ''||''). Los operadores de nivel bit tienen __mayor__ precedencia que los operadores de BooleEl compilador jamás podrá ayudarlo con el error de tipos si usó ''&'' cuando quería decir ''&&''En lo que concierne a la revisión de tiposresultan idénticas (en el sentido que ambas toman y producen enteros pues no existe un tipo de boole distintivo para ello).
  
  
-====Other Assignment Operators====+====Otros Operadores de Asignación====
  
 In addition to the plain ''='' operator, C includes many shorthand operators which represents variations on the basic ''=''. For example "''+=''" adds the right hand side to the left hand side. ''x = x + 10;'' can be reduced to ''x += 10;''. This is most useful if ''x'' is a long expression such as the following, and in some cases it may run a little faster. In addition to the plain ''='' operator, C includes many shorthand operators which represents variations on the basic ''=''. For example "''+=''" adds the right hand side to the left hand side. ''x = x + 10;'' can be reduced to ''x += 10;''. This is most useful if ''x'' is a long expression such as the following, and in some cases it may run a little faster.
Línea 335: Línea 335:
  
  
-=====Section 2 Control Structures ======+=====Sección Estructuras de Control ======
  
-====Curly Braces {} ====+====Llaves {} ====
  
 C uses curly braces ({}) to group multiple statements together. The statements execute in order. Some languages let you declare variables on any line (C++). Other languages insist that variables are declared only at the beginning of functions (Pascal). C takes the middle road -- variables may be declared within the body of a function, but they must follow a '{'. More modern languages like Java and C++ allow you to declare variables on any line, which is handy. C uses curly braces ({}) to group multiple statements together. The statements execute in order. Some languages let you declare variables on any line (C++). Other languages insist that variables are declared only at the beginning of functions (Pascal). C takes the middle road -- variables may be declared within the body of a function, but they must follow a '{'. More modern languages like Java and C++ allow you to declare variables on any line, which is handy.
  
  
-====If Statement====+====Declaración If====
  
 Both an if and an if-else are available in C. The <expression> can be any valid expression. The parentheses around the expression are required, even if it is just a single variable. Both an if and an if-else are available in C. The <expression> can be any valid expression. The parentheses around the expression are required, even if it is just a single variable.
Línea 362: Línea 362:
 </code> </code>
  
-====Conditional Expression -or- The Ternary Operator====+====Expresión Condicional -or- El Operador Ternario====
  
 The conditional expression can be used as a shorthand for some if-else statements. The general syntax of the conditional operator is: The conditional expression can be used as a shorthand for some if-else statements. The general syntax of the conditional operator is:
Línea 389: Línea 389:
 </code> </code>
  
-====Switch Statement====+====Declaración Switch====
  
-The switch statement is a sort of specialized form of if used to efficiently separate different blocks of code based on the value of an integer. The switch expression is evaluated, and then the flow of control jumps to the matching const-expression case. The case expressions are typically int or char constants. The switch statement is probably the single most syntactically awkward and error-prone features of the C language.+The ''switch'' statement is a sort of specialized form of ''if'' used to efficiently separate different blocks of code based on the value of an integer. The ''switch'' expression is evaluated, and then the flow of control jumps to the matching const-expression case. The ''case'' expressions are typically int or char constants. The ''switch'' statement is probably the single most syntactically awkward and error-prone features of the C language.
  
 <code c> <code c>
Línea 413: Línea 413:
 </code> </code>
  
-Each constant needs its own case keyword and a trailing colon (:). Once execution has jumped to a particular case, the program will keep running through all the cases from that point down -- this so called "fall through" operation is used in the above example so that expression-3 and expression-4 run the same statements. The explicit break statements are necessary to exit the switch. Omitting the break statements is a common error -- it compiles, but leads to inadvertent fall-through behavior.+Each constant needs its own case keyword and a trailing colon ('':''). Once execution has jumped to a particular case, the program will keep running through all the cases from that point down -- this so called "fall through" operation is used in the above example so that expression-3 and expression-4 run the same statements. The explicit break statements are necessary to exit the switch. Omitting the break statements is a common error -- it compiles, but leads to inadvertent fall-through behavior.
  
 Why does the switch statement fall-through behavior work the way it does? The best explanation I can think of is that originally C was developed for an audience of assembly language programmers. The assembly language programmers were used to the idea of a jump table with fall-through behavior, so that's the way C does it (it's also relatively easy to implement it this way.) Unfortunately, the audience for C is now quite different, and the fall-through behavior is widely regarded as a terrible part of the language. Why does the switch statement fall-through behavior work the way it does? The best explanation I can think of is that originally C was developed for an audience of assembly language programmers. The assembly language programmers were used to the idea of a jump table with fall-through behavior, so that's the way C does it (it's also relatively easy to implement it this way.) Unfortunately, the audience for C is now quite different, and the fall-through behavior is widely regarded as a terrible part of the language.
  
-==== While Loop ====+==== Bucle While ====
  
-The while loop evaluates the test expression before every loop, so it can execute zero times if the condition is initially false. It requires the parenthesis like the if.+The ''while'' loop evaluates the test expression before every loop, so it can execute zero times if the condition is initially false. It requires the parenthesis like the ''if''.
  
 <code c> <code c>
Línea 429: Línea 429:
  
  
-====Do-While Loop====+====Bucle Do-While ====
  
-Like a while, but with the test condition at the bottom of the loop. The loop body will always execute at least once. The do-while is an unpopular area of the language, most everyone tries to use the straight while if at all possible.+Like a ''while'', but with the test condition at the bottom of the loop. The loop body will always execute at least once. The ''do-while'' is an unpopular area of the language, most everyone tries to use the straight ''while'' if at all possible.
  
 <code c> <code c>
Línea 441: Línea 441:
 ====For Loop==== ====For Loop====
  
-The for loop in C is the most general looping construct. The loop header contains three parts: an initialization, a continuation condition, and an action.+The ''for'' loop in C is the most general looping construct. The loop header contains three parts: an initialization, a continuation condition, and an action.
  
 <code c> <code c>
Línea 463: Línea 463:
 ====Break==== ====Break====
  
-The break statement will move control outside a loop or switch statement. Stylistically speaking, break has the potential to be a bit vulgar. It's preferable to use a straight while with a single test at the top if possible. Sometimes you are forced to use a break because the test can occur only somewhere in the midst of the statements in the loop body. To keep the code readable, be sure to make the break obvious -- forgetting to account for the action of a break is a traditional source of bugs in loop behavior.+The ''break'' statement will move control outside a loop or ''switch'' statement. Stylistically speaking, ''break'' has the potential to be a bit vulgar. It's preferable to use a straight ''while'' with a single test at the top if possible. Sometimes you are forced to use a ''break'' because the test can occur only somewhere in the midst of the statements in the loop body. To keep the code readable, be sure to make the ''break'' obvious -- forgetting to account for the action of a ''break'' is a traditional source of bugs in loop behavior.
  
 <code c> <code c>
Línea 478: Línea 478:
  
  
-The break does not work with if. It only works in loops and switches. Thinking that a break refers to an if when it really refers to the enclosing while has created some high quality bugs. When using a break, it's nice to write the enclosing loop to iterate in the most straightforward, obvious, normal way, and then use the break to explicitly catch the exceptional, weird cases.+The ''break'' does not work with ''if''. It only works in loops and switches. Thinking that a ''break'' refers to an ''if'' when it really refers to the enclosing ''while'' has created some high quality bugs. When using a ''break'', it's nice to write the enclosing loop to iterate in the most straightforward, obvious, normal way, and then use the ''break'' to explicitly catch the exceptional, weird cases.
  
 ==== Continue ==== ==== Continue ====
  
-The continue statement causes control to jump to the bottom of the loop, effectively skipping over any code below the continue. As with break, this has a reputation as being vulgar, so use it sparingly. You can almost always get the effect more clearly using an if inside your loop.+The ''continue'' statement causes control to jump to the bottom of the loop, effectively skipping over any code below the continue. As with ''break'', this has a reputation as being vulgar, so use it sparingly. You can almost always get the effect more clearly using an ''if'' inside your loop.
  
 <code c> <code c>
Línea 497: Línea 497:
  
  
-=====Section Complex Data Types=====+=====Sección Tipos de Datos complejos =====
  
 C has the usual facilities for grouping things together to form composite types-- arrays and records (which are called "structures"). The following definition declares a type called "struct fraction" that has two integer sub fields named "numerator" and "denominator". If you forget the semicolon it tends to produce a syntax error in whatever thing follows the struct declaration. C has the usual facilities for grouping things together to form composite types-- arrays and records (which are called "structures"). The following definition declares a type called "struct fraction" that has two integer sub fields named "numerator" and "denominator". If you forget the semicolon it tends to produce a syntax error in whatever thing follows the struct declaration.
Línea 509: Línea 509:
 </code> </code>
  
-This declaration introduces the type struct fraction (both words are required) as a new type. C uses the period (.) to access the fields in a record. You can copy two records of the same type using a single assignment statement, however == does not work on structs.+This declaration introduces the type struct fraction (both words are required) as a new type. C uses the period (''.'') to access the fields in a record. You can copy two records of the same type using a single assignment statement, however ''=='' does not work on structs.
  
 <code c> <code c>
Línea 523: Línea 523:
 ====Arrays==== ====Arrays====
  
-The simplest type of array in C is one which is declared and used in one place. There are more complex uses of arrays which I will address later along with pointers. The following declares an array called scores to hold 100 integers and sets the first and last elements. C arrays are always indexed from 0. So the first int in scores array is scores[0] and the last is ''scores[99]''.+The simplest type of array in C is one which is declared and used in one place. There are more complex uses of arrays which I will address later along with pointers. The following declares an array called ''scores'' to hold 100 integers and sets the first and last elements. C arrays are always indexed from ''0''. So the first int in scores array is ''scores[0]'' and the last is ''scores[99]''.
  
 <code c> <code c>
Línea 554: Línea 554:
 It's a very common error to try to refer to non-existent ''scores[100]'' element. C does not do any run time or compile time bounds checking in arrays. At run time the code will just access or mangle whatever memory it happens to hit and crash or misbehave in some unpredictable way thereafter. "Professional programmer's language." The convention of numbering things ''0..(number of things - 1)'' pervades the language. To best integrate with C and other C programmers, you should use that sort of numbering in your own data structures as well. It's a very common error to try to refer to non-existent ''scores[100]'' element. C does not do any run time or compile time bounds checking in arrays. At run time the code will just access or mangle whatever memory it happens to hit and crash or misbehave in some unpredictable way thereafter. "Professional programmer's language." The convention of numbering things ''0..(number of things - 1)'' pervades the language. To best integrate with C and other C programmers, you should use that sort of numbering in your own data structures as well.
  
-====Multidimensional Arrays====+====Arreglos Multidimensionales ====
  
 The following declares a two-dimensional 10 by 10 array of integers and sets the first and The following declares a two-dimensional 10 by 10 array of integers and sets the first and
Línea 573: Línea 573:
  
  
-====Array of Structs====+====Arreglo de Estructuras====
  
-The following declares an array named "numbers" which holds 1000 ''struct fraction'' 's.+The following declares an array named "''numbers''" which holds 1000 ''struct fraction'' 's.
  
 <code c> <code c>
Línea 586: Línea 586:
 Here's a general trick for unraveling C variable declarations: look at the right hand side and imagine that it is an expression. The type of that expression is the left hand side. For the above declarations, an expression which looks like the right hand side (''numbers[1000]'', or really anything of the form ''numbers[...]'') will be the type on the left hand side (''struct fraction''). Here's a general trick for unraveling C variable declarations: look at the right hand side and imagine that it is an expression. The type of that expression is the left hand side. For the above declarations, an expression which looks like the right hand side (''numbers[1000]'', or really anything of the form ''numbers[...]'') will be the type on the left hand side (''struct fraction'').
  
-====Pointers====+====Punteros====
  
 A pointer is a value which represents a reference to another value sometimes known as the pointer's "pointee". Hopefully you have learned about pointers somewhere else, since the preceding sentence is probably inadequate explanation. This discussion will concentrate on the syntax of pointers in C -- for a much more complete discussion of pointers and their use see [[http://cslibrary.stanford.edu/102/| Pointers and Memory]]. A pointer is a value which represents a reference to another value sometimes known as the pointer's "pointee". Hopefully you have learned about pointers somewhere else, since the preceding sentence is probably inadequate explanation. This discussion will concentrate on the syntax of pointers in C -- for a much more complete discussion of pointers and their use see [[http://cslibrary.stanford.edu/102/| Pointers and Memory]].
  
-====Syntax====+====Sintaxis====
  
 Syntactically C uses the asterisk or "star" (''*'') to indicate a pointer. C defines pointer types based on the type pointee. A ''char*'' is type of pointer which refers to a single char. a struct fraction* is type of pointer which refers to a struct fraction. Syntactically C uses the asterisk or "star" (''*'') to indicate a pointer. C defines pointer types based on the type pointee. A ''char*'' is type of pointer which refers to a single char. a struct fraction* is type of pointer which refers to a struct fraction.
Línea 605: Línea 605:
 </code> </code>
  
-====The Floating "*"====+====El "*" Flotante====
  
 In the syntax, the star is allowed to be anywhere between the base type and the variable name. Programmer's have their own conventions-- I generally stick the * on the left with the type. So the above declaration of intPtr could be written equivalently... In the syntax, the star is allowed to be anywhere between the base type and the variable name. Programmer's have their own conventions-- I generally stick the * on the left with the type. So the above declaration of intPtr could be written equivalently...
Línea 616: Línea 616:
 </code> </code>
  
-====Pointer Dereferencing====+====Dereferenciado de Puntero====
  
 We'll see shortly how a pointer is set to point to something -- for now just assume the pointer points to memory of the appropriate type. In an expression, the unary * to the left of a pointer dereferences it to retrieve the value it points to. The following drawing shows the types involved with a single pointer pointing to a struct fraction. We'll see shortly how a pointer is set to point to something -- for now just assume the pointer points to memory of the appropriate type. In an expression, the unary * to the left of a pointer dereferences it to retrieve the value it points to. The following drawing shows the types involved with a single pointer pointing to a struct fraction.
Línea 668: Línea 668:
 </code> </code>
  
-====The Operator====+====El operador & ====
  
 The ''&'' operator is one of the ways that pointers are set to point to things. The ''&'' operator computes a pointer to the argument to its right. The argument can be any variable which takes up space in the stack or heap (known as an "LValue" technically). So ''&i'' and ''&(f1->numerator'') are ok, but ''&6'' is not. Use ''&'' when you have some memory, and you want a pointer to that memory. The ''&'' operator is one of the ways that pointers are set to point to things. The ''&'' operator computes a pointer to the argument to its right. The argument can be any variable which takes up space in the stack or heap (known as an "LValue" technically). So ''&i'' and ''&(f1->numerator'') are ok, but ''&6'' is not. Use ''&'' when you have some memory, and you want a pointer to that memory.
Línea 692: Línea 692:
 A pointer can be assigned the value 0 to explicitly represent that it does not currently have a pointee. Having a standard representation for "no current pointee" turns out to be very handy when using pointers. The constant NULL is defined to be 0 and is typically used when setting a pointer to NULL. Since it is just 0, a NULL pointer will behave like a boolean false when used in a boolean context. Dereferencing a NULL pointer is an error which, if you are lucky, the computer will detect at runtime -- whether the computer detects this depends on the operating system. A pointer can be assigned the value 0 to explicitly represent that it does not currently have a pointee. Having a standard representation for "no current pointee" turns out to be very handy when using pointers. The constant NULL is defined to be 0 and is typically used when setting a pointer to NULL. Since it is just 0, a NULL pointer will behave like a boolean false when used in a boolean context. Dereferencing a NULL pointer is an error which, if you are lucky, the computer will detect at runtime -- whether the computer detects this depends on the operating system.
  
-====Pitfall -- Uninitialized Pointers====+====Pitfall -- Punteros no Inicializados====
  
 When using pointers, there are two entities to keep track of. The pointer and the memory it is pointing to, sometimes called the "pointee". There are three things which must be done for a pointer/pointee relationship to work... When using pointers, there are two entities to keep track of. The pointer and the memory it is pointing to, sometimes called the "pointee". There are three things which must be done for a pointer/pointee relationship to work...
Línea 718: Línea 718:
 Of course your code won't be so trivial, but the bug has the same basic form: declare a pointer, but forget to set it up to point to a particular pointee. Of course your code won't be so trivial, but the bug has the same basic form: declare a pointer, but forget to set it up to point to a particular pointee.
  
-====Using Pointers====+====Uso de Punteros====
  
 Declaring a pointer allocates space for the pointer itself, **but it does not allocate space for the pointee**. The pointer must be set to point to something before you can dereference it. Declaring a pointer allocates space for the pointer itself, **but it does not allocate space for the pointee**. The pointer must be set to point to something before you can dereference it.
Línea 742: Línea 742:
 So far we have just used the & operator to create pointers to simple variables such as i. Later, we'll see other ways of getting pointers with arrays and other techniques. So far we have just used the & operator to create pointers to simple variables such as i. Later, we'll see other ways of getting pointers with arrays and other techniques.
  
-====C Strings====+====Cadenas de C====
  
 C has minimal support of character strings. For the most part, strings operate as ordinary arrays of characters. Their maintenance is up to the programmer using the standard facilities available for arrays and pointers. C does include a standard library of functions which perform common string operations, but the programmer is responsible for the managing the string memory and calling the right functions. Unfortunately computations involving strings are very common, so becoming a good C programmer often requires becoming adept at writing code which manages strings which means managing pointers and arrays. C has minimal support of character strings. For the most part, strings operate as ordinary arrays of characters. Their maintenance is up to the programmer using the standard facilities available for arrays and pointers. C does include a standard library of functions which perform common string operations, but the programmer is responsible for the managing the string memory and calling the right functions. Unfortunately computations involving strings are very common, so becoming a good C programmer often requires becoming adept at writing code which manages strings which means managing pointers and arrays.
Línea 773: Línea 773:
 If the code instead tried to store the string "I enjoy languages which have good string support" into localString, the code would just crash at run time since the 10 character array can contain at most a 9 character string. The large string will be written passed the right hand side of localString, overwriting whatever was stored there. If the code instead tried to store the string "I enjoy languages which have good string support" into localString, the code would just crash at run time since the 10 character array can contain at most a 9 character string. The large string will be written passed the right hand side of localString, overwriting whatever was stored there.
    
-====String Code Example====+====Ejemplo de Cadena de código====
  
 Here's a moderately complex for loop which reverses a string stored in a local array. It demonstrates calling the standard library functions ''strcpy()'' and ''strlen()'' and demonstrates that a string really is just an array of characters with a '\0' to mark the effective end of the string. Test your C knowledge of arrays and ''for'' loops by making a drawing of the memory for this code and tracing through its execution to see how it works. Here's a moderately complex for loop which reverses a string stored in a local array. It demonstrates calling the standard library functions ''strcpy()'' and ''strlen()'' and demonstrates that a string really is just an array of characters with a '\0' to mark the effective end of the string. Test your C knowledge of arrays and ''for'' loops by making a drawing of the memory for this code and tracing through its execution to see how it works.
Línea 803: Línea 803:
 </code> </code>
  
-===="Large Enough" Strings====+====Cadenas "Large Enough"====
  
 The convention with C strings is that the owner of the string is responsible for allocating array space which is "large enough" to store whatever the string will need to store. Most routines do not check that size of the string memory they operate on, they just assume its big enough and blast away. Many, many programs contain declarations like the following... The convention with C strings is that the owner of the string is responsible for allocating array space which is "large enough" to store whatever the string will need to store. Most routines do not check that size of the string memory they operate on, they just assume its big enough and blast away. Many, many programs contain declarations like the following...
Línea 850: Línea 850:
  
  
-===== Section Functions =====+===== Sección Funciones =====
  
 All languages have a construct to separate and package blocks of code. C uses the "function" to package blocks of code. This article concentrates on the syntax and peculiarities of C functions. The motivation and design for dividing a computation into separate blocks is an entire discipline in its own. All languages have a construct to separate and package blocks of code. C uses the "function" to package blocks of code. This article concentrates on the syntax and peculiarities of C functions. The motivation and design for dividing a computation into separate blocks is an entire discipline in its own.
Línea 907: Línea 907:
 </code> </code>
  
-====Call by Value vs. Call by Reference====+====Llamada por Valor vs. Llamada por Referencia====
  
 C passes parameters "by value" which means that the actual parameter values are copied into local storage. The caller and callee functions do not share any memory -- they each have their own copy. This scheme is fine for many purposes, but it has two disadvantages. C passes parameters "by value" which means that the actual parameter values are copied into local storage. The caller and callee functions do not share any memory -- they each have their own copy. This scheme is fine for many purposes, but it has two disadvantages.
Línea 918: Línea 918:
 Some languages support reference parameters automatically. C does not do this -- the programmer must implement reference parameters manually using the existing pointer constructs in the language. Some languages support reference parameters automatically. C does not do this -- the programmer must implement reference parameters manually using the existing pointer constructs in the language.
  
-====Swap Example====+====Ejemplo de Swap====
  
-The classic example of wanting to modify the caller's memory is a swap() function which exchanges two values. Because C uses call by value, the following version of Swap will not work...+The classic example of wanting to modify the caller's memory is a ''swap()'' function which exchanges two values. Because C uses call by value, the following version of Swap __will not work__...
  
 <code c> <code c>
Línea 940: Línea 940:
 ''Swap()'' does not affect the arguments a and b in the caller. The function above only operates on the copies of a and b local to ''Swap()'' itself. This is a good example of how "local" memory such as ( x, y, temp) behaves -- it exists independent of everything else only while its owning function is running. When the owning function exits, its local memory disappears. ''Swap()'' does not affect the arguments a and b in the caller. The function above only operates on the copies of a and b local to ''Swap()'' itself. This is a good example of how "local" memory such as ( x, y, temp) behaves -- it exists independent of everything else only while its owning function is running. When the owning function exits, its local memory disappears.
  
-====Reference Parameter Technique====+===Técnica de parámetro Reference===
  
-To pass an object X as a reference parameter, the programmer must pass pointer to instead of X itself. The formal parameter will be a pointer to the value of interest. The caller will need to use & or other operators to compute the correct pointer actual parameter. The callee will need to dereference the pointer with ''*'' where appropriate to access the value of interest. Here is an example of a correct ''Swap()'' function.+To pass an object X as a reference parameter, the programmer must pass __a pointer to X__ instead of X itself. The formal parameter will be a pointer to the value of interest. The caller will need to use ''&'' or other operators to compute the correct pointer actual parameter. The callee will need to dereference the pointer with ''*'' where appropriate to access the value of interest. Here is an example of a correct ''Swap()'' function.
  
 <code c> <code c>
Línea 969: Línea 969:
 ====const==== ====const====
  
-The qualifier const can be added to the left of a variable or parameter type to declare that the code using the variable will not change the variable. As a practical matter, use of const is very sporadic in the C programming community. It does have one very handy use, which is to clarify the role of a parameter in a function prototype...+The qualifier ''const'' can be added to the left of a variable or parameter type to declare that the code using the variable will not change the variable. As a practical matter, use of ''const'' is very sporadic in the C programming community. It does have one very handy use, which is to clarify the role of a parameter in a function prototype...
  
-  void foo(const struct fraction* fract);+<code c> 
 +void foo(const struct fraction* fract); 
 +</code>
  
 In the ''foo()'' prototype, the const declares that ''foo()'' does not intend to change the struct fraction pointee which is passed to it. Since the fraction is passed by pointer, we could not know otherwise if ''foo()'' intended to change our memory or not. Using the const, ''foo()'' makes its intentions clear. Declaring this extra bit of information helps to clarify the role of the function to its implementor and caller. In the ''foo()'' prototype, the const declares that ''foo()'' does not intend to change the struct fraction pointee which is passed to it. Since the fraction is passed by pointer, we could not know otherwise if ''foo()'' intended to change our memory or not. Using the const, ''foo()'' makes its intentions clear. Declaring this extra bit of information helps to clarify the role of the function to its implementor and caller.
  
  
-====Bigger Pointer Example====+===Bigger Pointer Example===
  
 The following code is a large example of using reference parameters. There are several common features of C programs in this example...Reference parameters are used to allow the functions ''Swap()'' and ''IncrementAndSwap()'' to affect the memory of their callers. The following code is a large example of using reference parameters. There are several common features of C programs in this example...Reference parameters are used to allow the functions ''Swap()'' and ''IncrementAndSwap()'' to affect the memory of their callers.
Línea 1010: Línea 1012:
  
  
-=====Section 5 Odds and Ends=====+=====Sección 5 Odds and Ends=====
  
 ====main()==== ====main()====

Este sitio web utiliza cookies para guardar datos esenciales de su actividad, como su autenticación. Al entrar acepta el uso de cookies.

Más información