Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

168
Vistas
¿Puedes pasar una cadena por valor en C?

Las cadenas se interpretan como punteros cuando las pasa a una función en C, por ejemplo, func(str) pasará un puntero al bloque de memoria llamado str. Entonces, de forma predeterminada, las cadenas ya son punteros cuando se pasan a una función. ¿Hay alguna manera de pasar una cadena por valor en la que no tenga que terminar manipulando el contenido de str ?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Primero, ¿qué es una cadena? Es una matriz de caracteres y luego un \0 . Sólo para asegurarnos de que todos estamos de acuerdo en eso.

Entonces, la pregunta es, ¿puedes pasar una matriz de caracteres por valor? Y la respuesta es sí, pero solo si está dentro de una estructura o unión:

 struct String40Chars { char str[41]; }; void f(struct String40Chars s) { // s was passed by value - including s.str }

Sin embargo, no puede pasar una matriz directamente debido a una peculiaridad histórica:

 void f(char str[41]) { // you would think this would work, // but actually, the compiler converts it to void f(char *str) }

Eso es desafortunado para las personas que realmente quieren pasar matrices por valor.

Por suerte, normalmente no es necesario. En todos los casos que se me ocurren, un puntero es lo suficientemente bueno y también más rápido, ya que no necesita copiar la matriz. Tal vez pueda explicar por qué necesita pasar una matriz por valor.

PD: hablas de que "las cadenas son punteros", pero eso no tiene sentido. Las cadenas son matrices. Puede tener punteros a matrices, pero el puntero no es la matriz.

over 4 years ago · Santiago Trujillo Denunciar

0

La única forma de lograr una semántica de valor con argumentos de cadena en C es tener una estructura o unión que envuelva la cadena.

Algo como:

 #define STR_BY_VALUE_MAX_LENGTH 128 typedef struct StrByValue_ { char str[STR_BY_VALUE_MAX_LENGTH]; } StrByValue; void f(StrByValue strByVal) { // Changes to strByVal will not affect the caller }

Por supuesto, la persona que llama tendrá que inicializar el objeto StrByValue copiando la cadena (por ejemplo, usando strcpy) en el campo str . También puede agregar un campo len a la estructura StrByValue si no desea utilizar cadenas terminadas en cero.

over 4 years ago · Santiago Trujillo Denunciar

0

Otra respuesta es almacenar la cadena en la memoria de la pila, que no se puede cambiar de tamaño después de la inicialización, lo que no creo que sea un corredor largo. Según yo, la cadena debe almacenarse en la memoria del montón para que podamos expandirla más tarde, piense en una estructura de datos que se expande cuando se agrega algo al final.

Para implementar esto bien y con algo de sintaxis azucarada, necesitamos crear 3 funciones, a saber, init_string() , append_string() y free_string() .

  • init_string() : inicializa el puntero y asigna len = INIT_STR_LEN
  • append_string() : se puede usar para la concatenación de dos cadenas
  • free_string() : libera el montón asignado ptr , por lo tanto, no hay fugas de memoria

Código:

 #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct { char *ptr; size_t len; } string; string init_string(const char *s) { string x; x.len = strlen(s); x.ptr = malloc(x.len + 1); if (!x.ptr) { fprintf(stderr, "err: memory can't be allocated\n"); exit(EXIT_FAILURE); } memcpy(x.ptr, s, x.len + 1); return x; } void append_string(string *s, const char *str) { if (!str || !s) { fprintf(stderr, "err: null was passed\n"); exit(EXIT_FAILURE); } size_t str_l = strlen(str); s->ptr = realloc(s->ptr, s->len + str_l + 1); if (!s->ptr) { fprintf(stderr, "err: memory can't be allocated\n"); exit(EXIT_FAILURE); } memcpy(s->ptr + s->len, str, str_l + 1); s->len += str_l; } void free_string(string *s) { if (!s) { fprintf(stderr, "err: null was passed\n"); exit(EXIT_FAILURE); } free(s->ptr); s->len = 0; } void foo(string a) // got the value of a { // cannot modified permanently } void bar(string *a) // got the address of a { // can be modified permanently } int main(void) { string str = init_string("Hello world, I'm a c-string."); puts(str.ptr); append_string(&str, "stackoverflow"); puts(str.ptr); free_string(&str); return EXIT_SUCCESS; }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda