Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

170
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda