Search code examples
cstructpass-by-referencepass-by-valuefunction-declaration

Changing the value of an element in a struct


I'm new to structs. I am trying to write a program that has a struct, and the struct is supposed to store a character array and its length. I want to be able change the length's value as I would be creating functions like trimming/concatenating the array. Here is a code I wrote:

#include <stdio.h>
#include <stdlib.h>
struct strstruct{
unsigned int length;
char string[20];
};
typedef struct strstruct stru;
int strleng(stru A){
  int i=0;
  while(A.string[i]!='\0'){
    i++;
  }
  A.length =i;
  return i;
}
int main(){

  stru A = {1,
 {'a','b','c','d','e','f'}
  };
  
  printf("%d %d\n",strleng(A),A.length);
  return 0;
}

The value of A.length is not changing inspite of calling strleng.
(i)Why?
(ii) Is there another way to do it?


Solution

  • For starters the order of evaluation of arguments in a function call is unspecified.

    So in this call

     printf("%d %d\n",strleng(A),A.length);
    

    the evaluation of the argument expression A.length can occur before calling the function strleng or vice versa.

    Secondly the function strleng declared like

    int strleng(stru A);
    

    deals with a copy of the original object A declared in main and used as an argument. So changing the copy does not influence on the original object.

    You need to pass the object by reference through a pointer to it.

    unsigned int strleng( stru *A){
      unsigned int i=0;
      while(A->string[i]!='\0'){
        i++;
      }
      A->length =i;
      return i;
    }
    

    and in main you should write for example

    unsigned int n = strleng( &A );
    printf("%u %u\n", n, A.length );
    

    Pay attention to that on one hand, the data member length is declared as having the type unsigned int

    unsigned int length;
    

    On the other hand, within your original function strleng you are using an object of the signed type int and the function return type is also int. The function should use at least the same type unsigned int instead of the type int.