Why do some C / C ++ functions use pointers as parameters?

I am coming from C # and I am learning C ++ (with this tutorial ), so I have a relatively unreasonable amount of knowledge about memory, but the only thing I see in pointers is โ€œsaving spaceโ€ and repeating through arrays. So why do functions like scanf take pointers as parameters? For instance:

printf("What your name?: "); and then: scanf("%s",&userName) . Doesn't it make sense to just pass this variable as an argument? Book C, which I looked at, said that using the variable itself would produce unexpected results, but I donโ€™t understand why. Can someone please enlighten me in C ++ mod? I switched from learning C because I realized how much I love OOP.

+4
source share
8 answers

C and C ++ pass variables by value; a formal parameter is another object in memory from the actual parameter. Thus, if a formal parameter changes in a function, the value of the actual parameter does not change.

By passing a pointer, the function can change the contents of the actual parameter:

 void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } ... swap(&x, &y); 

Thus, writing to *a in swap equivalent to writing to x in the caller.

Pointers in C serve three main purposes:

  • Fake semantics of pass-by-reference, as described above (as Carl points out in the comments, C ++ has a mechanism that supports true passing by reference);
  • Tracking dynamically allocated memory ( malloc , calloc and realloc memory allocation functions and C ++ operator pointer value new );
  • Creating dynamic data structures (trees, lists, queues, stacks, etc.).
+6
source

There are 3 different ways to pass a variable to a function in C ++, pass by copy, pass by reference, and pass by pointer.

 #include <iostream> void passByCopy(int a) { a += 1; } void passByReference(int &a) { a += 1; } void passByPointer(int *a) { (*a) += 1; // De-reference then increment. } int main() { int a = 0; // Passing by copy, creates a copy of the 'a' object, then sends it to the function. passByCopy(a); std::cout << a << std::endl; // Outputs 0 // Passing by reference, causes the 'a' object in the function to reference the 'a' // object at this scope. The value of 'a' will change. passByReference(a); std::cout << a << std::endl; // Outputs 1 // Passing by pointer, does almost the same thing as a pass by reference, except a // pointer value can by NULL, while a reference can't. passByPointer(&a); std::cout << a << std::endl; // Outputs 2 } 

Using the scanf function, the purpose of the function is to pass values โ€‹โ€‹to variables in the current area, so it cannot use pass by copy. It does not use pass by reference for two reasons: one of them is the old C function, so there was no way to pass it by reference when it was written. Secondly, it is a variational function, which means that inside the function receives a list of pointers, and not a series of arguments.

+6
source

All parameters are passed by value to C. If you want to pass by reference, you need to explicitly pass the address of the variable in question. Passing by reference is important when you want a function to modify a passed variable.

C ++ has links, but since C ++ code often calls C library functions, you still see the same syntax that is sometimes used in C ++.

+4
source

In your specific example, scanf is part of the C standard library. C does not have a string class, so strings are represented as arrays of characters.

In C, the address of the first character is usually passed when strings are required. It can be &str[0] or str . I am not sure if &username correct if it expects char * , I think it depends on the username.

+2
source

C has no idea about passing by reference and can only return one value. Thus, the traditional purpose of passing with a pointer is to allow the called function to write to a variable so that the caller can read what is written.

C ++ has the ability to pass by reference, but scanf and printf are C functions that are also available when created as C ++, so they are not available.

EDIT: explain further, even putting the variable arguments next to the problem, in the following code:

 void calledFunction(int var1, int var2) { var1 = 23; var2 = 19; } void callingFunction(void) { int v1 = 9, v2 = 18; calledFunction(v1, v2); printf("%d %d", v1, v2); } 

Exit "9 18". calledFunction gets local copies of v1 and v2 because C passes by value, which means that the values โ€‹โ€‹of v1 and v2 were passed, but no other link was saved in the originals. Therefore, the fact that he changes his copies does not affect the originals.

+1
source

There are no references in C; all arguments are passed by value.

If scanf is in C #, then its parameters will be preceded by the out or ref keyword, and no pointers are needed. Skipping pointers allow the scanf function to write some values โ€‹โ€‹to any location pointed to by pointers.

In C ++, however, there are links, albeit different from what you know from C #. However, if you are using the iostream library, not stdio , which was inherited from C ++ with C, then you would not have to use pointers in this way. You just write:

 String username; cin >> username; 
+1
source

Another use of pointers that I don't see in other announcements is that this is one of two ways that the C function can return multiple values. The C function is defined to return a single object, but can take many arguments. If your multi-valued function always returns the same set of values, the convenience question is whether to wrap the values โ€‹โ€‹in the structure and return the function of the struct function or to have function pointers through which it can write values.

The pointer parameter parameter becomes much more attractive if the function also needs to return a status or error code (because it is silly to write it through a pointer, forcing the caller to highlight another variable and prevent standard idioms, for example if(f()==ERROR)... ) And if the set of values โ€‹โ€‹is not predictable at compile time (for example, scanf, which should interpret the format string at run time), then the pointer options become the only (reasonable) option.

Edit: In your example, scanf("%s",&username); The intended username is an array type or a pointer to the repository, suitable for storing a character string, you do not need to pass an address. If it is an array, it will be passed as a pointer implicitly. And if it is already a pointer, then using the address you get a pointer to a pointer that is not suitable for storing a string. So leave & here.

+1
source

scanf is a function of C. C has no references, so it must use pointers to write to arguments. In addition, scanf is a varargs function, so it accepts variable numbers of arguments. And varargs functions can only accept built-in types: pointers (to whatever), integers, double.

0
source

All Articles