[Solucionado] Constantes de carácter y constantes de cadena de carácteres

Iniciado por Caster, 19 Febrero 2012, 15:19 PM

0 Miembros y 1 Visitante están viendo este tema.

Caster

Hola a todos,

llevo tiempo con una duda que no doy resuelto:

Las constantes de carácter es un carácter encerrado entre comillas simples, que se puede representar por un valor numérico segun la tabla ASCII.

Las contantes de cadena de carácter es un número cualquiera de caracteres consecutivos encerrados entre comillas dobles. He leído que llevan un caracter nulo al final que indica el fin de la cadena, "\0".

Estaba probando la función:

toupper

Convierte una letra a mayúscula, tengo este código:

#include <stdio.h>

int main() {

char i = 'a';
printf("%c", toupper(i));

getchar();
return 0;
}


Y el resultado es: "A", perfecto.

Con este código:

#include <stdio.h>

int main() {

char i = "a";
printf("%c", toupper(i));

getchar();
return 0;
}


El resultado es "D", no entiendo porque. Creía que tenia entendida la diferencia entra las dos pero veo que no. Querría saber porque pasa esto.

Saludos

rir3760

Los caracteres literales son una forma mas fácil de indicar un entero de tipo "signed int", por ejemplo 'A' en lugar de 65.

Las cadenas literales como "Hola" se almacenan en memoria y cuando se utilizan (salvo ciertas excepciones) resultan en la dirección en memoria del primer elemento del array (se consideran arrays de caracteres).

Tu problema se encuentra en la linea:
char i = "a";
Ya que en buen cristiano se puede traducir a "Tómese la dirección en memoria del array indicado y almacenese en la variable en cuestión". Después tratas de imprimir la dirección (mas bien lo que se pudo almacenar de ella en un carácter) y por ello el resultado.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

Caster

Entiendo todo, hasta que dices donde está el error. Ya sabía que el error estaba ahí, solo quiero saber porque ocurre eso y no entendido lo que has dicho  :-X

rir3760

Por partes.

Primero debo indicar que me equivoque con la explicación de la declaración, como dicen en mi rancho: "metí las patas" (las cuatro ;-) ).

----

Bueno, vamos a corregir eso. Cuando en la declaración de un array se utiliza una secuencia de caracteres delimitada por comillas dobles, por ejemplo:
char palabra[] = "hola";
Esa secuencia solo es una forma mas corta de indicar una lista de valores y la declaración anterior es equivalente a:
char palabra[] = {'h', 'o', 'l', 'a', '\0'};

En base a ello la declaración en tu programa:
char i = "a";

/* ==> */

char i = {'a', '\0'};

Es un error ya que una lista de valores solo puede utilizarse en la declaración de un agregado (una estructura o array) y la variable "i" no lo es.

----

Por otra parte en expresiones las secuencias de caracteres delimitadas por comillas dobles se conocen como "cadenas literales", estas secuencias se almacenan en algún lugar en memoria, su tipo es array de caracteres y si se trata de modificar una resulta en "comportamiento no definido" (cualquier cosa puede pasar).

Peor todavía, esas cadenas literales cuando se usan en una expresión tienen usualmente el mismo efecto que los arrays: resultan en la dirección en memoria del primer elemento de este.

Si todo eso te resulta complicado lo siento, el tema de los arrays y punteros es uno de los mas complicados en el lenguaje C.

Un programa demostrando lo anterior es:
#include <stdio.h>
#include <stdlib.h>

#define CAD_EJEMPLO  "123456789"

int main(void)
{
   int i;
   
   printf("La cadena de ejemplo es \"%s\"\n", CAD_EJEMPLO);
   
   /* 1) Direccion donde se almacena la cadena literal */
   printf("Direccion base: %p\n", (void *) CAD_EJEMPLO);
   
   /* 2) Espacio utilizado en memoria por la literal */
   printf("Espacio utilizado: %lu\n", (unsigned long) sizeof CAD_EJEMPLO);
   
   /* 3) Literales iguales se almacenan en el mismo lugar? */
   if (CAD_EJEMPLO == CAD_EJEMPLO)
      puts("Misma ubicacion");
   else
      puts("Distinta ubicacion");
   
   /* 4) Impresion de cada uno de los caracteres de la literal */
   for (i = 0; CAD_EJEMPLO[i] != '\0'; i++)
      putchar(CAD_EJEMPLO[i]);
   putchar('\n');
   
   return EXIT_SUCCESS;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language