¿Cuáles son los detalles de la definición de una cadena en C?

10

Se supone que debo responder una pregunta de tarea para una de mis clases. Específicamente, se supone que debo decir si ciertas matrices en C se consideran cadenas o no. Basado en este artículo ( https://www.geeksforgeeks.org/strings-in-c-2/ ) Sé que las cadenas son una serie de caracteres con el terminador nulo al final.

Mi bloqueo principal es una parte de la pregunta que se hace sobre una matriz que se ve así:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

Obviamente, se trata de una serie de caracteres con un carácter de terminación nulo al final. Sin embargo, ¿todavía se considera una cadena ya que también tiene un carácter de terminación nulo en el medio? ¿Cómo afectará eso a la cuerda?

EDITAR: Basado en comentarios, he proporcionado la redacción real de la pregunta:

"¿Cuál de las siguientes matrices puede considerarse" cadenas "con el propósito de usarlas como argumentos para strcpy (), strncpy (), strcmp (), strncmp () y funciones de cadena similares (indicar todas las aplicaciones)?

EDITAR: envié un correo electrónico a mi profesor al respecto ya que la pregunta parecía ambiguamente redactada (como señalaron varias personas). Si alguien tiene curiosidad, me dijo "Sí, es una cadena. La clave es que hay un carácter nulo. Pero, por supuesto, eso afectará cualquier operación de cadena; la cadena termina en el carácter nulo".

organismo estatal semiautónomo
fuente
44
Se podría decir que es la cadena "CS"con algunos bytes de basura añadidos (en cuyo caso el carácter NUL final es irrelevante). Pero no es una cadena "en su conjunto". - Sin embargo, alimentar esto a strcpyetc. no hará que su PC explote porque estas funciones "verán" solo la "CS"parte.
Hagen von Eitzen
2
c1 puede usarse absolutamente como argumento para strcmp(). Si se puede usar como argumento para mutar funciones de cadena depende de factores adicionales que no se proporcionan.
EOF
2
El contenido de c1es mutable, por lo que no veo por qué no podría ser un argumento de destino válido strcpyo similar, a menos que no sea lo suficientemente grande como para acomodar la cadena de origen. Eso no haría que no sea una cadena, simplemente no una adecuada para un propósito determinado.
John Bollinger
1
En general, estoy de acuerdo en que la pregunta está ambiguamente redactada. La expresión c1satisfaría los requisitos básicos para los argumentos de cadena para todas las funciones de cadena (estrechas) de la biblioteca estándar, incluidas todas aquellas específicamente nombradas, pero el comportamiento podría no ser lo que la persona que llama espera o desea (incluso ignorando los comportamientos indefinidos que podrían surgir).
John Bollinger
1
Tenga en cuenta que el tipo no necesita ser char. Cualquier tipo de personaje servirá.
chux - Restablece a Monica

Respuestas:

8

c1es en su mayoría [1] a equivalente &c1[0], que es la celebración de una cadena, "CS".

Hay una segunda cadena al acecho allí, "324"a partir de las &c1[3]- pero siempre y cuando se accede c1como c1, la cadena "CS"es todas las funciones strcpy()et al. vería.


[1]: c1es una matriz, &c1[0]es un puntero.

DevSolar
fuente
Entonces, ¿es apropiado usarlo c1como cadena de destino en un strcpy()comando? La pregunta es ambigua, en el mejor de los casos.
Andrew Henle
1
Por supuesto, podría usarlo c1como argumento para strcpy(). Es una cuerda perfectamente ordinaria en todos los sentidos. Las cadenas ordinarias a menudo contienen restos de basura después de sus terminadores. El hecho de que esta basura esté codificada en el programa da la impresión de que el autor tiene la intención de usarla c1de forma no encadenada, pero eso no era parte de la pregunta.
Lee Daniel Crocker
" c1es equivalente a &c1[0]" engaños. c1es una matriz &c1[0]Es un puntero.
chux - Restablece a Monica
2

Si desea conocer los detalles de la definición de una cadena en C, vaya a la fuente.

Del estándar C90 :

7 biblioteca

7.1 Introducción

7.1.1 Definiciones de términos
Una cadena es una secuencia contigua de caracteres terminados por e incluyendo el primer carácter nulo. Un "puntero a" una cadena es un puntero a su carácter inicial (con la dirección más baja). La "longitud" de una cadena es el número de caracteres que preceden al carácter nulo y su "valor" es la secuencia de los valores de los caracteres contenidos, en orden.

(No hubo cambios relevantes en los estándares posteriores).

Por lo tanto, c1contiene dos cadenas consecutivas, "CS" y "324", pero no es en sí misma una cadena.

Si pasamos una matriz a una función, se desintegra a un puntero a su primer elemento, por lo tanto, +c1apunta a una cadena (la primera), que es lo suficientemente buena para cualquier función que espera un puntero a cadena. No apunta a una cadena "CS \ 0324", pero probablemente sea lo suficientemente buena para la pregunta de su instructor, que es ambigua.

Deduplicador
fuente
44
Yo diría que incluso con esta definición, c1 es claramente la cadena "CS". Período. El hecho de que pueda contener bytes distintos de cero después del terminador es irrelevante: muchas cadenas serán así en su vida útil.
Lee Daniel Crocker
+c1apunta a una cadena, porque c1comienza con una cadena. Sin embargo, eso de ninguna manera, forma o forma hace c1una cadena.
Deduplicador
2
Es la dirección de una sección de memoria que contiene algunos caracteres terminados en un byte cero. Si printf () funciona bien con un% s, daría un número perfectamente bueno pasado a strlen (), funcionaría si se pasa a strcpy (), etc. A mí me parece una cadena.
Lee Daniel Crocker
Por supuesto. Pero las matrices ciertamente pueden ser cadenas.
Lee Daniel Crocker
0

Agregando a la respuesta de @ DevSolar, algo que descubrí después de jugar con la cadena dada, si fuera:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

Si saca esta cadena, obtendrá CS03240y el tamaño de esta cadena es 7. En lo que a mi entender se refiere, \\0se usa para denotar el carácter nulo ( es decir \0 ). Si lo haces:

printf("\0");

No ve nada en el registro de salida, pero si lo hace:

printf("\\0");

Verá un \0, algo que se espera porque para generar caracteres especiales como barras invertidas o comillas, debe usar un \junto con ellos.

Algo que me desconcierta es la salida CS03240y su tamaño 7. Es de conocimiento común que el tamaño de una cadena es el número de caracteres que contiene más uno (para el carácter nulo). Además, el tamaño es de 7 incluso para la cadena, char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };.

Entonces, tal vez un seguimiento de esta pregunta, ¿qué está pasando aquí?

rasengan__
fuente
1
'\\0'No es un personaje nulo . Es una constante de múltiples caracteres. Tiene un valor definido de implementación ciertamente fuera del rango de char. c1[]no es una cadena ya que carece de un carácter nulo . "la salida de esta cadena" probablemente da como resultado un comportamiento indefinido .
chux - Restablece a Monica
No te entendí exactamente aunque busqué constantes de varios personajes. Si c1 [] no es una cadena porque no tiene un carácter nulo al final, entonces ¿por qué el tamaño sale como 7 en el caso inicial publicado por el OP?
rasengan__
char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };es de tamaño 7 porque se inicializa con 7 valores. Su tamaño no tiene nada que ver con las cuerdas . char c1[] = { 1, 2, 3, 4, 5, 6, 7 };todavía lo haría tamaño 7.
chux - Reinstale a Monica
¿En cuanto a la matriz c1contiene una picadura? Esa es una cuestión aparte. Ver también
chux - Restablecer a Monica