Understanding functions and pointers in C - c

This is a very simple question but what does the following function prototype mean?
int square( int y, size_t* x )
what dose the size_t* mean? I know size_t is a data type (int >=0). But how do I read the * attached to it? Is it a pointer to the memory location for x? In general I'm having trouble with this stuff, and if anybody could provide a handy reference, I'd appreciate it.
Thanks everybody. I understand what a pointer is, but I guess I have a hard hard time understanding the relationship between pointers and functions. When I see a function prototype defined as int sq(int x, int y), then it is perfectly clear to me what is going on. However, when I see something like int sq( int x, int* y), then I cannot--for the life of me--understand what the second parameter really means. On some level I understand it means "passing a pointer" but I don't understand things well enough to manipulate it on my own.

How about a tutorial on understanding pointers?
In this case however, the pointer is probably used to modify/return the value. In C, there are two basic mechanisms in which a function can return a value (please forgive the dumb example):
It can return the value directly:
float square_root( float x )
{
if ( x >= 0 )
return sqrt( x );
return 0;
}
Or it can return by a pointer:
int square_root( float x, float* result )
{
if ( x >= 0 )
{
*result = sqrt( result );
return 1;
}
return 0;
}
The first one is called:
float a = square_root( 12.0 );
... while the latter:
float b;
square_root( 12.00, &b );
Note that the latter example will also allow you to check whether the value returned was real -- this mechanism is widely used in C libraries, where the return value of a function usually denotes success (or the lack of it) while the values themselves are returned via parameters.
Hence with the latter you could write:
float sqresult;
if ( !square_root( myvar, &sqresult ) )
{
// signal error
}
else
{
// value is good, continue using sqresult!
}

*x means that x is a pointer to a memory location of type size_t.
You can set the location with x = &y;
or set the value were x points to with: *x = 0;
If you need further information take a look at: Pointers

The prototype means that the function takes one integer arg and one arg which is a pointer to a size_t type. size_t is a type defined in a header file, usually to be an unsigned int, but the reason for not just using "unsigned int* x" is to give compiler writers flexibility to use something else.
A pointer is a value that holds a memory address. If I write
int x = 42;
then the compiler will allocate 4 bytes in memory and remember the location any time I use x. If I want to pass that location explicitly, I can create a pointer and assign to it the address of x:
int* ptr = &x;
Now I can pass around ptr to functions that expect a int* for an argument, and I can use ptr by dereferencing:
cout << *ptr + 1;
will print out 43.
There are a number of reasons you might want to use pointers instead of values. 1) you avoid copy-constructing structs and classes when you pass to a function 2) you can have more than one handle to a variable 3) it is the only way to manipulate variables on the heap 4) you can use them to pass results out of a function by writing to the location pointed to by an arg

Pointer Basics
Pointers And Memory

In response to your last comment, I'll try and explain.
You know that variables hold a value, and the type of the variable tells you what kind of values it can hold. So an int type variable can hold an integer number that falls within a certain range. If I declare a function like:
int sq(int x);
...then that means that the sq function needs you to supply a value which is an integer number, and it will return a value that is also an integer number.
If a variable is declared with a pointer type, it means that the value of that variable itself is "the location of another variable". So an int * type variable can hold as its value, "the location of another variable, and that other variable has int type". Then we can extend that to functions:
int sqp(int * x);
That means that the sqp function needs to you to supply a value which is itself the location of an int type variable. That means I could call it like so:
int p;
int q;
p = sqp(&q);
(&q just means "give me the location of q, not its value"). Within sqp, I could use that pointer like this:
int sqp(int * x)
{
*x = 10;
return 20;
}
(*x means "act on the variable at the location given by x, not x itself").

size_t *x means you are passing a pointer to a size_t 'instance'.
There are a couple of reasons you want to pass a pointer.
So that the function can modify the caller's variable. C uses pass-by-value so that modifying a parameter inside a function does not modify the original variable.
For performance reasons. If a parameter is a structure, pass-by-value means you have to copy the struct. If the struct is big enough this could cause a performance hit.

There's a further interpretation given this is a parameter to a function.
When you use pointers (something*) in a function's argument and you pass a variable you are not passing a value, you are passing a reference (a "pointer") to a value. Any changes made to the variable inside the function are done to the variable to which it refers, i.e. the variable outside the function.
You still have to pass the correct type - there are two ways to do this; either use a pointer in the calling routine or use the & (addressof) operator.
I've just written this quickly to demonstrate:
#include <stdio.h>
void add(int one, int* two)
{
*two += one;
}
int main()
{
int x = 5;
int y = 7;
add(x,&y);
printf("%d %d\n", x, y);
return 0;
}
This is how things like scanf work.

int square( int y, size_t* x );
This declares a function that takes two arguments - an integer, and a pointer to unsigned (probably large) integer, and returns an integer.
size_t is unsigned integer type (usually a typedef) returned by sizeof() operator.
* (star) signals pointer type (e.g. int* ptr; makes ptr to be pointer to integer) when used in declarations (and casts), or dereference of a pointer when used at lvalue or rvalue (*ptr = 10; assigns ten to memory pointed to by ptr). It's just our luck that the same symbol is used for multiplication (Pascal, for example, uses ^ for pointers).
At the point of function declaration the names of the parameters (x and y here) don't really matter. You can define your function with different parameter names in the .c file. The caller of the function is only interested in the types and number of function parameters, and the return type.
When you define the function, the parameters now name local variables, whose values are assigned by the caller.
Pointer function parameters are used when passing objects by reference or as output parameters where you pass in a pointer to location where the function stores output value.
C is beautiful and simple language :)

U said that u know what int sq(int x, int y) is.It means we are passing two variables x,y as aguements to the function sq.Say sq function is called from main() function as in
main()
{
/*some code*/
x=sr(a,b);
/*some other code*/
}
int sq(int x,int y)
{
/*code*/
}
any operations done on x,y in sq function does not effect the values a,b
while in
main()
{
/*some code*/
x=sq(a,&b);
/*some other code*/
}
int sq(int x,int* y)
{
/*code*/
}
the operations done on y will modify the value of b,because we are referring to b
so, if you want to modify original values, use pointers.
If you want to use those values, then no need of using pointers.

most of the explanation above is quite well explained. I would like to add the application point of view of this kind of argument passing.
1) when a function has to return more than one value it cannot be done by using more than one return type(trivial, and we all know that).In order to achieve that passing pointers to the function as arguments will provide a way to reflect the changes made inside the function being called(eg:sqrt) in the calling function(eg:main)
Eg: silly but gives you a scenario
//a function is used to get two random numbers into x,y in the main function
int main()
{
int x,y;
generate_rand(&x,&y);
//now x,y contain random values generated by the function
}
void generate_rand(int *x,int *y)
{
*x=rand()%100;
*y=rand()%100;
}
2)when passing an object(a class' object or a structure etc) is a costly process (i.e if the size is too huge then memory n other constraints etc)
eg: instead of passing a structure to a function as an argument, the pointer could be handy as the pointer can be used to access the structure but also saves memory as you are not storing the structure in the temporary location(or stack)
just a couple of examples.. hope it helps..

2 years on and still no answer accepted? Alright, I'll try and explain it...
Let's take the two functions you've mentioned in your question:
int sq_A(int x, int y)
You know this - it's a function called sq_A which takes two int parameters. Easy.
int sq_B(int x, int* y)
This is a function called sq_B which takes two parameters:
Parameter 1 is an int
Parameter 2 is a pointer. This is a pointer that points to an int
So, when we call sq_B(), we need to pass a pointer as the second
parameter. We can't just pass any pointer though - it must be a pointer to an int type.
For example:
int sq_B(int x, int* y) {
/* do something with x and y and return a value */
}
int main() {
int t = 6;
int u = 24;
int result;
result = sq_B(t, &u);
return 0;
}
In main(), variable u is an int. To obtain a pointer to u, we
use the & operator - &u. This means "address of u", and is a
pointer.
Because u is an int, &u is a pointer to an int (or int *), which is the type specified by parameter 2 of sq_B().
Any questions?

Related

While swapping two values, the input of the function must be two const pointers and the return should be void

I've written the code for passing the values normally with pointers My question is how to pass these values i.e. a & b as constant pointers, if it is not already.
void swap(int *x, int *y)
{
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
return;
}
int main () {
int a = 20;
int b = 12345;
printf("Before swap, value of a : %d\n", a );
printf("Before swap, value of b : %d\n", b );
swap(&a, &b);
printf("After swap, value of a : %d\n", a );
printf("After swap, value of b : %d\n", b );
return 0;
}
const in C generally goes after the type, and the * is part of the type, so the type declaration of an integer pointer constant is:
int * const
You may have tried int const *, and found that to not work. That's because, to repeat, generally const applies to the thing on its left.
Opinion: This is why I hate the pattern of writing const first, like const int. It only works because the language has a special case - if there is nothing to the left of the const, it applies to the thing on its right - and since most people learn by example, every occurrence of const at the beginning of a type declaration contributes to mis-teaching people trying to learn the language.
Tip: I like reading and saying const as "which is constant", because that phrase clearly refers to the thing before it, so it matches the left-to-right order of the parts of a type declaration: int const then reads as "an integer which is constant" and int * const reads as "an integer's address which is constant".
Putting that together with your swap function we get
void swap(int * const x, int * const y)
Opinion: This is also why I dislike * in a declaration "touching" the name. I do int * foo instead of int *foo because it's more consistent with other type declarations like int * const foo, which I feel is more important than consistency with the unary operator placement in dereferences like *foo.
But you should know that in C, or at least in all real and most conceivable implementations of C, it doesn't actually change code behavior to make function parameters const like that - the parameter itself is private to the function, so the function can't change it. The only way it could realistically make a difference for the actual code is if you had a C compiler which could better optimize a function if you tell it that it won't be modifying its own parameters, but most optimizing compilers can just notice if a parameter isn't being modified within a function. Of course, it can still be useful as a way of telling people reading your code what your intent with the parameters is, and if you have a habit of declaring things const any time you don't have specific intent to change them, you're more likely to have computers catch certain mistakes (like if you have a parameter named similarly to a variable in your function, and you mean to modify one but accidentally type the other - if the other was const, simple tooling can catch the mistake).
Arguments are passed by value, and values are not const or non-const; only objects can be qualified that way. You can qualify the function parameters (which are objects that are initialized to the argument values), and that just means the function will not change the values of the parameters:
void swap(int * const x, int * const y)
{
// x and y are not changed, although the objects they point to are changed.
int temporary = *x;
*x = *y;
*y = temporary;
}
If you want to make the parameter types pointers to const objects, that is also possible. As long as a pointer points to an object that was not defined with const, the behavior of removing the const through a conversion and using it to modify the object is defined:
void swap(const int *x, const int *y)
{
/* ncx and ncy are set to the original pointers to non-const
that became the pointers to const that are x and y.
*/
int *ncx = (int *) x, *ncy = (int *) y;
int temporary = *ncx;
*ncx = *ncy;
*ncy = temporary;
}

Why is this function not pure?

In the Wikipedia article https://en.wikipedia.org/wiki/Pure_function#Impure_functions it says that the following function is not pure.
int f(int* x)
{
return *x;
}
Why is that? The function would return the same value for the same argument right? Would it be considered pure if it was a non-mutable reference, as in the following?
int f2(const int* x)
{
return *x;
}
f isn't pure because its return value isn't necessary the same for the same arguments. You could call f twice with the same inputs and get different outputs. The following program demonstrates this:
#include <stdio.h>
int main() {
int i = 3;
int * const x = &i;
printf("%d\n", f(x));
i = 4;
printf("%d\n", f(x));
return 0;
}
Because x doesn't change between the two calls, the second call to f(x) could be optimized away (in favour of reusing the result from the first call) if f was pure. Obviously, that could produce the wrong result, so f isn't pure.
f2 isn't pure for the same reason.
Rule 1 says:
Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
The point is that the argument is not the value pointed by x but rather the address of the pointer. You're passing an address to the function.
Since you can change the pointed data and pass the same address then you have different return values.
Of course this wouldn't be true if f or f2 returned int* instead that int. In that case the same argument would lead to the same return value.

how to pass a condition as parameter to function in C?

I have created an array of function pointers to swap two variables.
pointer pointing to these functions namely: swap1, swap2. swap3 and swap4.
swap2 is swaping using pointer passed as arguments.
but while declaring the function pointer, only int and int are passed as arguments. after compiling this causes many warnings.
so do we have a better way of passing the argument, where we put condition in function call itself.
code is given below.
#include <stdio.h>
int swap1(int ,int );
int swap2(int* ,int* );
int swap3(int ,int );
int swap4(int, int);
int swap1(int a,int b)
{
int temp=a;
a=b;
b=temp;
printf("swapped with 3rd variable :%d, %d\n", a,b);
}
int swap2(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
printf("swapped with pointer :%d, %d\n", *a,*b);
}
int swap3(int a,int b)
{
a+=b;
b=a-b;
a-=b;
printf("swapped with 2 variable :%d, %d\n", a,b);
}
int swap4(int a,int b)
{
a=a^b;
b=a^b;
a=a^b;
printf("swapped with bitwise operation :%d, %d\n", a,b);
}
int main()
{
int ch;
int a=3;
int b=4;
printf("enter the option from 0 to 3\n");
scanf("%d",&ch);
int (*swap[4])(int, int) ={swap1,swap2,swap3,swap4};// function pointer
/*can we pass something like int(*swap[4]( condition statement for 'pointer to variable' or 'variable')*/
if (ch==1)// at '1' location, swap2 is called.
{
(*swap[ch])(&a,&b);//passing the addresses
}
else
{
(*swap[ch])(a,b);
}
return 0;
}
some warnings are as follows.
at line 36 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
Well yes. There are a number of problems with your code, but I'll focus on the ones to which the warnings you presented pertain. You declare swap as an array of four pointers to functions that accept two int arguments and return an int:
int (*swap[4])(int, int)
Your function swap2() is not such a function, so a pointer to it is not of the correct type to be a member of the array. Your compiler might do you a better favor by rejecting the code altogether instead of merely emitting warnings.
Having entered a pointer to swap2() into the array anyway, over the compiler's warnings, how do you suppose the program could call that function correctly via the pointer? The type of the pointer requires function arguments to be ints; your compiler again performs the dubious service of accepting your code with only warnings instead of rejecting it.
Since the arguments in fact provided are the correct type, it might actually work on systems and under conditions where the representations of int and int * are compatible. That is no excuse, however, for writing such code.
Because pointers and ints are unchanged by the default argument promotions, one alternative would be to omit the prototype from your array declaration:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
That says that each pointer points to a function that returns int and accepts a fixed but unspecified number of arguments of unspecified types. At the point of the call, the actual arguments will be subject to the default argument promotions, but that is not a problem in this case. This option does prevent the compiler from performing type checking on the arguments, but in fact you cannot do this correctly otherwise.
Your compiler might still warn about this, or could be induced to warn about it with the right options, but the resulting code nevertheless conforms and does the right thing, in the sense that it calls the pointed-to functions with the correct arguments.
To deal with the warnings first: You declare an array of functions which take int parameters. This means that swap2 is incompatible with the type of element for the array you put it in. This will generate a diagnostic.
Furthermore, when you call one of the functions in the array, the same array declaration tells the compiler that the parameters need to be ints not pointers to int. You get two diagnostics here, one for each parameter.
To fix the above all your functions need to have compatible prototypes with the element type of the array. Should it be int or int*? This brings us to the other problem.
C function arguments are always pass by value. This means that the argument is copied from the variable onto the stack (or into the argument register depending on the calling convention and argument count - for the rest of this post, I'll assume arguments are placed on the stack for simplicity's sake). If it's a literal, the literal value is put on the stack. If the values on the stack are changed by the callee no attempt is made by the caller, after the function returns, to put the new values back in the variables. The arguments are simply thrown away.
Therefore, in C, if you want to do the equivalent of call by reference, you need to pass pointers to the variables you use as arguments as per swap2. All your functions and the array should therefore use int*. Obviously, that makes one of swap1 and swap2 redundant.
The correct array definition is
int (*swap[4])(int*, int*) = {swap1, swap2, swap3, swap4};
and the definition of each function should be modified to take int* parameters. I'd resist the temptation to use int (*swap[4])() simply because it circumvents type safety. You could easily forget the & in front of an int argument when the called function is expecting a pointer which could be disastrous - the best case scenario when you do that is a seg fault.
The others have done great work explaining what the problems are. You should definitely read them first.
I wanted to actually show you a working solution for that sort of problem.
Consider the following (working) simple program :
// main.c
#include <stdio.h>
void swap1(int* aPtr, int* bPtr) {
printf("swap1 has been called.\n");
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
void swap2(int* aPtr, int* bPtr) {
printf("swap2 has been called.\n");
*aPtr += *bPtr;
*bPtr = *aPtr - *bPtr;
*aPtr -= *bPtr;
}
int main() {
int a = 1, b = 2;
printf("a is now %d, and b is %d\n\n", a, b);
// Declare and set the function table
void (*swapTbl[2])(int*, int*) = {&swap1, &swap2};
// Ask for a choice
int choice;
printf("Which swap algorithm to use? (specify '1' or '2')\n>>> ");
scanf("%d", &choice);
printf("\n");
// Swap a and b using the right function
swapTbl[choice - 1](&a, &b);
// Print the values of a and b
printf("a is now %d, and b is %d\n\n", a, b);
return 0;
}
First of, if we try to compile and execute it:
$ gcc main.c && ./a.out
a is now 1, and b is 2
Which swap algorithm to use? (specify '1' or '2')
>>> 2
swap2 has been called.
a is now 2, and b is 1
As myself and others mentioned in answers and in the comments, your functions should all have the same prototype. That means, they must take the same arguments and return the same type. I assumed you actually wanted to make a and b change, so I opted for int*, int* arguments. See #JeremyP 's answer for an explanation of why.

Pass by value-doesn't execute as I want it [duplicate]

This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 7 years ago.
I do not understand the concept of pass by value in C. Here is my function:
void add(int x){
x = x+1;
}
and when I call the function:
int y=3;
add(y);
but when I compile, I still get 3. I've been told it has something to do with pass-by-value but I still do not understand? Can anyone explain why?
Pass by value creates a copy of the argument. It is this copy that is changed in the function
void add(int x){
x = x+1;
}
Thus the change you make is made to the copy and not the variable in your main scope (that you are expecting to see changed).
If you want to change a variable within a function by passing it as a parameter you cannot pass by value. You could change your function to pass by pointer like this
void add(int* x){
*x = *x + 1;
}
and pass the address of an integer to the function like this
int y=3;
add(&y);
within main()
The pointer is still passed by value so it is a copy of the pointer that is being acted on, but this doesn't matter as you are not changing the pointer itself, you are changing the value of the variable it points to.
This function:
void add(int x) {
x = x + 1;
}
Essentially says this: create a function named add, that returns nothing (void), and takes a single integer argument x. Then you call the function:
y = 3;
add(y);
This says "Set the variable named y to 3. Now call the add() function passing as an argument the current value of y, namely 3. This is no different from
add(3);
The argument x is entirely local to the function add(). It exists only inside the function, and does not affect anything outside it.
So your function dutifully adds 1 to the number you gave it, and then throws it away. Just like you told it to.
C has no "pass by reference" like other languages, where you can tell a function to act on a variable itself rather than its current value. It does, however, have pointers, which can accomplish similar things.
All function arguments in C are passed by value. That means that the parameter (in this case, x defined in add) is initialized to a copy of the value of the argument (in this case, y, which has the value 3).
Since x is a local variable, executing
x = x + 1;
changes the value of x, but that change has no effect after the function returns and x no longer exists.
Note that the argument doesn't have to be the name of a variable. You can legally call your function like this:
add(42);
x is initialized to 42 -- but x = x + 1 certainly isn't going to change the value of 42.
If you want to modify the value, you can have the function return the new value:
int add(int x) {
return x + 1;
}
The caller can do anything it likes with the result, including assigning it back to the variable:
int y = 3;
y = add(y);
Or you can pass the address of the object you want to modify:
int add(int *x) {
*x = *x + 1;
}
and then the caller can do this:
int y = 3;
add(&y);
This is still pass-by-value, but the value being passed is a pointer value, the address of x. It's how we can emulate pass-by-reference in C.
You can solve above by using the code :
int add(int x)
{ x=x+1;
return x;}
then use
a new variable like
k= add(y);
and then print k.

C Function implementation - with Pointer vs without Pointer

I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string.
pointerstring vs normal.
Also if you want to provide more information about when to use pointers that would be great. I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value.
#include <stdio.h>
void pointerstring(char *s);
void normal(char s[]);
int main() {
char string[20];
pointerstring(string);
printf("\nPointer: %s\n",string);
normal(string);
printf("Normal: %s\n",string);
}
void pointerstring(char *s) {
sprintf(s,"Hello");
}
void normal(char s[]) {
sprintf(s,"World");
}
Output:
Pointer: Hello
Normal: World
In a function declaration, char [] and char * are equivalent. Function parameters with outer-level array type are transformed to the equivalent pointer type; this affects calling code and the function body itself.
Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt e.g. to take the sizeof of an outer-level fixed-length array type parameter:
void foo(char s[10]) {
printf("%z\n", sizeof(s)); // prints 4 (or 8), not 10
}
When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const), you are explicitly giving the function permission to modify the object or array the pointer points to.
One of the problems in C is that arrays are second-class citizens. In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information).
Therefore, it makes no difference whether you take an array as T* arg or T arg[] — the latter is a mere synonym for the former. Both are pointers to the first character of the string variable defined in main(), so both have access to the original data and can modify it.
Note: C always passes arguments per copy. This is also true in this case. However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address, so that the object referred to is accessible through two different copies of its address.
With pointer Vs Without pointer
1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function.
With pointers
...
int a = 10;
func(&a);
...
void func(int *x);
{
//do something with the value *x(10)
*x = 5;
}
Without pointers
...
int a = 10;
a = func(a);
...
int func(int x);
{
//do something with the value x(10)
x = 5;
return x;
}
2) Global or static variable has life time scope and local variable has scope only to a function. If we want to create a user defined scope variable means pointer is requried. That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function.
3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers.
struct data;
struct data
{
int no1, no2, ans;
void (*pfAdd)(struct data*);
void (*pfSub)(struct data*);
void (*pfMul)(struct data*);
void (*pfDiv)(struct data*);
};
void add(struct data* x)
{
x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...
4) Consider a structure data which size s is very big. If we want to send a variable of this structure to another function better to send as reference. Because this will reduce the activation record(in stack) size created for the new function.
With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func
...
struct data a;
func(&a);
...
Without Pointers - It will requires s bytes in activation record(in stack) of function func. Conside the s is sizeof(struct data) which is very big value.
...
struct data a;
func(a);
...
5) We can change a value of a constant variable with pointers.
...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...
in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value.
So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf));

Resources