Why do some functions that work with C strings start with *?

Asked

Viewed 205 times

3

In one of our classes we were taught that when a function receives as a parameter an array it is actually receiving the memory position in which it is allocated so it is not necessary to return any value because what will be executed within the procedure automatically will be changing in vector/string in itself. But some functions are starting with a * and returning a vector. Ex:

int strlen(char *s){
  int i = 0;
  while(s[i]!='\0'){
    i++;
  }
  return i;
}

Example of a standard function that returns the number of elements in string.

char *strcpy(char *dest, char *orig){
    int i;
    for(i=0; orig[i]!='\0'; i++){
        dest[i] = orig[i];
    }  
    dest[i] = '\0';
    return dest;
}

Example of a function that is returning a string/vector.

Why some functions start with * and consequently return a vector?

  • The asterisk is part of the return. strcpy is a function that returns char*: char pointer (the fact that the asterisk is near the function name or the type name makes no difference).

2 answers

8


Because that particular function should do that. Look at her name: string copy. She must copy a string. What you have learned is correct, if you receive a pointer, anything that moves the content pointed by this variable will change the content of the original memory, since it is the same location. But in this case you don’t want to touch what already exists, you want to create a copy of that content elsewhere. So you need to create a new object, not the same object. So after this function finishes creating this new object it must return to where this object is, so it returns a pointer to this object new object.

Another way to ensure this is to pass this address as an argument. And in fact this occurs in this function. Maybe your question is why do both.

The philosophy of C is to always let the programmer take care of the memory management, because it will probably do the best for each situation. So if you are the one who has to allocate the memory to the copy of string you must pass this address as argument, and indeed this is being done.

There according to what you learned the copy will be placed in this last address, changing this new object. Great, it’s settled, you don’t have to return anything, right?

Yeah, right. But it is common to use this function to allocate in another variable and for convenience gave the option to return the same address you passed to the use function as new object.

Better do

char* nova = strcpy(malloc(10), "texto");

than

char* nova = malloc(10);
strcpy(nova, "texto");

I put in the Github for future reference.

  • I understand. Thank you very much for the clarification.

  • I never imagined using the return of malloc as a direct parameter of strcpy and things like that

  • 1

    @Jeffersonqueso thing that I talk about a lot and a lot of people don’t because nobody wants to see their flaws pointed out, is that if you don’t know what each character of the code does, even the spaces, you haven’t mastered the programming yet. When you start thinking about what can go there, almost like a compiler, you start producing better code. The rest is following the recipes you’ve learned. I myself still slide here and there. A lot of very experienced people have certain difficulties because they follow recipes instead looking for the best solution. They think it’s not necessary, which makes them senior at one point and junior at another.

  • It’s something I once read, dealt with in this article Meet your compiler and in this presentation Optimization of source code.

  • Exactly, you have to know every detail. If you look I talk about these optimizations here on the site.

1

Being pedestrian in reading function statement

This mistake happens due to the School of Style code of the person who wrote this function. I will write equivalent headers, each in a distinct style:

char *strcpy(char *dest, char *orig);
char* strcpy(char *dest, char *orig);
char *strcpy(char* dest, char* orig);
char * strcpy(char * dest, char * orig);
char* strcpy(char* dest, char* orig);

What is the difference between the above statements? For the compiler, none. There are for those who write and for those who read, but this is only at the level of code style.

Why there are these different style schools?

Well, each one has a proposal, a defended value. It’s kind of like asking "if you have Cubism, why did you use Dadaism?"...

If anyone writing with the pointer indicator always on the left side thought that the pointer indicator should be isolated from the words that surround it, the left style would have succumbed long ago.

I am from school who, in variable declaration, use the pointer indicator always pasted in the variable name. Why? Beauty counts? Furthermore, because the following two statements are identical:

int *p, i;
int* p, i;

In both cases, a pointer is being created p and a whole i. The idea of the school that I follow is to always show in the variable that it has this pointer indicator, avoiding that someone unintentionally interprets the i be another pointer to integer.

Thus, it creates the habit of always separating the type from the *, what may not be healthy. In functions, for example, I don’t see why reading disambiguation, only use because yes. Note that, as each argument comes preceded of its type, also becomes irrelevant the reason for reading improvement.

Summary

You wouldn’t say that char* strcpy(char* dest, char* orig); begins with *, would you say? So it doesn’t return a vector because it starts with *, but returns a pointer because the type of return declared is character pointer char*.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.