C function explain - c

#include <stdio.h>
float orizousa(int n[]);
int main() {
int a[12];
int i;
printf("grapse tous sintelestes kai to apotelesma tis prwtis eksiswsis \n (me seira:1os-2os-3os sintelestis - apotelesma) :");
for(i=0; i<=11; i++) {
scanf(" %d",&a[i]);
}
float g = orizousa(a);
printf(" %f",g);
return 0;
}
float orizousa(int a[]) {
float d,dx1,dx2,dx3,x1,x2,x3;
d = a[0]*a[4]*a[8] + a[1]*a[5]*a[6] + a[2]*a[3]*a[7] - a[2]*a[4]*a[7] - a[1]*a[3]*a[8] - a[0]*a[5]*a[7] ;
dx1 = a[9]*a[4]*a[8] + a[1]*a[5]*a[11] + a[2]*a[10]*a[7] - a[2]*a[4]*a[7] - a[1]*a[10]*a[8] - a[9]*a[5]*a[7] ;
dx2 = a[0]*a[10]*a[8] + a[0]*a[5]*a[6] + a[2]*a[3]*a[11] - a[2]*a[10]*a[11] - a[1]*a[3]*a[8] - a[0]*a[5]*a[11] ;
dx3 = a[0]*a[4]*a[11] + a[1]*a[10]*a[6] + a[9]*a[3]*a[7] - a[9]*a[4]*a[7] - a[1]*a[3]*a[11] - a[0]*a[10]*a[7] ;
return d;
}
In this code, in the line that says
float g = orizousa(a);
why do we put only a in, and not a[] for example??
How can I return 2 values, for example d and dx, from one function??

when it comes to array just the name, passes the array's address and the function accepting it will be pointing to the same memory address. it more like reference variable in C++.
u cant return more than one value at a time. if the data is of similar type u can copy to an array and pass the array back

Arrays and pointers are intimately related. When you write "g=orizousa(a)" you are passing the function a copy of the address of the first element of the array a.
To return two values from a function you can either pass the address of the two variables you want to change or put them into a structure and return the structure.
void foo( int* x, int* y ) {
*x = 1; *y = 2;
}
called as
int xx = 0;
int yy = 0;
foo(&xx,&yy);
or as a struct
typedef struct {
int x;
int y;
} args;
either pass in as argument
void foo(args* arg) {
args.x=1;
args.y=2;
}
called as
args arg;
foo(&arg);
or returned
args foo() {
args arg = { 1,2 };
return arg;
}
called as
args arg = foo();

float g=orizousa(a);
int a[]
a is an array of integer type where the variable name 'a' denotes the reference of array a.
function orizousa takes a reference parameter of integer type. thats why you have to pass a instead of a[]
if you want to return d and dx then simply add another reference to your function.
orizousa(int a[],float pReturn[])
{
....
pReturn[0]=d;
pReturn[1]=dx;
}

why we put only 'a' in, and not a[] for example??
When passing array as arguments to functions in C, we have to pass the variable name only, unless you want to pass only one element of the array, which in that case would be float g = orizousa(a[2]) for example. But the function orizousa receives an array, so you have to pass the entire array.
and how can i return 2 values??
There is no way to return 2 values in C from a function. But what you can do is pass variables as reference. You can do something like this:
#include <stdio.h>
float orizousa(int n[]);
int main()
{
int a[12];
int i;
printf("grapse tous sintelestes kai to apotelesma tis prwtis eksiswsis \n (me seira:1os-2os-3os sintelestis - apotelesma) :");`enter code here`
for(i=0;i<=11;i++)
{ scanf(" %d",&a[i]);}
float d, dx1, dx2, dx3;
float g=orizousa(a, &d, &dx1, &dx2, &dx3);
printf(" %f",g);
return 0;
}
float orizousa(int a[], float *d, float *dx1, float *dx2, float *dx3)
{
*d=a[0]*a[4]*a[8] + a[1]*a[5]*a[6] + a[2]*a[3]*a[7] - a[2]*a[4]*a[7] - a[1]*a[3]*a[8] - a[0]*a[5]*a[7] ;
*dx1=a[9]*a[4]*a[8] + a[1]*a[5]*a[11] + a[2]*a[10]*a[7] - a[2]*a[4]*a[7] - a[1]*a[10]*a[8] - a[9]*a[5]*a[7] ;
*dx2=a[0]*a[10]*a[8] + a[0]*a[5]*a[6] + a[2]*a[3]*a[11] - a[2]*a[10]*a[11] - a[1]*a[3]*a[8] - a[0]*a[5]*a[11] ;
*dx3=a[0]*a[4]*a[11] + a[1]*a[10]*a[6] + a[9]*a[3]*a[7] - a[9]*a[4]*a[7] - a[1]*a[3]*a[11] - a[0]*a[10]*a[7] ;
}

When you are passing an array to the function orizousa, you are passing the address of the array, not an actual copy (atleast in this case). In C, a actually stores the address of the first element of the array. So, you are passing the address of the first element of the array. *a will print the value of the first element. we cannot pass a[] because that is a syntax error.
To return 2 values, you can declare a variable in the main function and pass it as a reference variable to orizousa. Then you can return d and store the value of dx1 in the reference variable.

Related

int are mutable in C. What is the purpose of using pointer to change the value of mutable object?

Can anyone explain me the difference among these two?
#include <stdio.h>
void main() {
int a = 10;
int *p = &a;
*p = 11;
}
and
#include <stdio.h>
void main() {
int a = 10;
a = 11;
}
For starters pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
The presented two programs actually are equivalent except that in the first program the variable a is changed through a pointer to it.
As it is written in the C Standard (6.2.5 Types, p.#20)
... A pointer type describes an object whose value provides a
reference to an entity of the referenced type.
This property of pointers is used in C to implement the mechanism of passing objects by reference to functions.
Consider the following program.
#include <stdio.h>
void f( int x )
{
x = 10;
}
void g( int *px )
{
*px = 10;
}
int main(void)
{
int x = 0;
printf( "Before calling f x = %d\n", x );
f( x );
printf( "After calling f x = %d\n", x );
x = 0;
printf( "\nBefore calling g x = %d\n", x );
g( &x );
printf( "After calling g x = %d\n", x );
return 0;
}
The program output is
Before calling f x = 0
After calling f x = 0
Before calling g x = 0
After calling g x = 10
As you can see after calling the function f the value of the variable x declared in main was not changed. The problem is that the function deals with a copy of the value of the variable x declared in main. That is the function parameter is a local variable of the function that was initialized by the value of the variable x declared in main. Changing the local variable does not influence on the variable x declared in main.
But when the variable x is passed to the function g by reference through a pointer to it then the function is able to change the original variable x declared in main by means of dereferencing the passed pointer.
Also bear in mind that when you allocate a memory dynamically then allocated objects do not have names. You only have pointers to dynamically allocated objects. For example
int *px = malloc( sizeof( int ) );
So to change the allocated object you also need to dereference the pointer
*px = 10;
In this case nothing, but suppose that you want to call a function, if want to edit the value of a FROM INSIDE that function, you'll need to use pointers.
#include <stdio.h>
void set_a(int *p, int val)
{
*p = val;
}
int main()
{
int a = 2;
printf("a is: %d\n", a); // a is 2
set_a(&a, 5);
printf("a is: %d\n", a); // a is 5
}
that's just one use case. for instance, when using heap allocations, you'll need to use pointers.
The two programs have the same observable effect.
What is the purpose of using pointer to change the value of mutable object?
One good use is to be able to reuse logic. Write it once and use it many times.
Example:
void foo(int *X, int *Y) {
/* some complex calculation */
*X = *X + *Y + 1;
*Y = *Y + *X + 2;
}
Now, you could use the function to do this "complex" calculation on different variables. You only need to write and test it properly once and can then reuse it many times.
int main() {
int a = 10, b = 20, c = 30, d = 40;
foo(&a, &b);
foo(&c, &d);
//...
}
Demo

Understanding fractional knapsack, arrays and pointers

Just started learning C programming and decided to take a class in algorithmic Toolbox on Coursera. One of the challenges is writing a code using fractional knapsack, maximizing the value of loot and a pseudo code was given to help in coding the solution. Below are the pseudo code and the code I wrote for the pseudo code.
#include<stdio.h>
int min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
int knapsack(int value[], int weight[])
{
int capacity = 100;
int val = 0;
int array[] = { 0 };
for (int i = 1; i < capacity; i++)
{
if (capacity == 0)
{
return val;
}
for (int i = 1; i < capacity; i++)
{
if (weight[i] > 0 && (value[i] / weight[i]))
{
int a = min(weight[i], capacity);
val = val + a * (value[i] / weight[i]);
weight[i] = weight[i] - a;
array[i] = array[i] + a;
capacity = capacity - a;
}
}
}
return val;
}
int main()
{
int value[100];
int weight[100];
scanf("%d", &value[100]);
scanf("%d", &weight[100]);
printf("%d", knapsack(value[100], weight[100]));
return 0;
}
pseudo code
Knapsack(W, w1,v1,......wn,vn)
A <-- [0,0,], V <-- 0;
repeat n times:
if W = 0:
return (V,A)
select i with Wi > 0 and max vi/wi
a <-- min(wi, W)
V <-- V + a(vi/wi)
wi <-- wi - a, A[i] <-- A[i] + a, W <-- W - a
return (V, A)
I am getting errors when I compile such as "passing argument 1 of 'knapsack' makes pointer from integer without a cast [-Wint-conversion]"
printf("%d", knapsack(value[100],weight[100]));
"expected int * but argument is of type 'int'"
int knapsack(int value[], int weight[])
I also want to know if it is a good practice to declare int value[], int weight[] in the function int knapsack argument and also more explanation in using arrays and pointers in situations like this.
int knapsack(int value[], int weight[])
The above statement gives the compiler the information about HOW the function should be called (type of arguments) and WHAT the function will return.
It says the function knapsack will return an integer value (the 1st int).
Its name is knapsack (case-sensitive).
It expects two arguments: an integer array (named value) and an integer array (named weight).
Points 1, 2 and 3 together make up the signature of a function.
To call the function you have to pass 2 integer arrays as its arguments.
The mistake : value[100] corresponds to an INTEGER ENTRY in the array and not the array itself.
To pass the array you should pass the array name as its argument, which your function expects.
Call the function like this: knapsack(value, weight)
value corresponds the array value and weight corresponds to the array weight
Also, passing value[100] corresponds to some garbage value that is not within the array bounds as you can only access elements ranging from value[0] to value[99] (0-based indexing).

passing address in c

In the following code example:
typedef struct data{
char ch;
int n;
int n2;
}DATA;
void Func3(DATA d){
int sum;
sum = d.ch + d.n;
d.ch = 'c';
d.n = 0x77;
}
void Func4(DATA &d){
int sum;
sum = d.ch + d.n;
d.ch = 'k';
//d.n = 0x88;
}
int WINAPI WinMain(HINSTANCE hlnst, HINSTANCE hprev,
LPSTR lpCmd, int nShow)
{
DATA dt;
dt.ch = 'a';
dt.n = 10;
dt.n2 = 20;
Func3(dt);
Func4(dt);
return 0;
}
Are Func3() and Func4() the same thing?
Are both functions pass-by-reference?
Is there any difference between the two functions?
You are compiling this with a C++ compiler. DATA &d is not syntactically correct in C.
In Func, the compiler essentially writes DATA d = dt before the function body is entered.
In Func2 that "assignment" does not happen. The C++ compiler sets d to be a reference to dt. So changes to d in Func2 are reflected in the caller as changes to dt.
In your specific case though, an optimising compiler will recognise that both functions are no-ops, and so will probably compile them out.
In C there is no reference '&' type variables like in C++.
You have to pass the address to get the same affect. FUNC2() in C with 'd' as pass by reference will look like below:
void Func2(DATA *d){
int sum;
sum = d->ch + d->n;
}
When in C there is used words "pass by reference" then it means that an object is passed to a function indirectly by means of a pointer to the object.
Consider the following demonstrative program
#include <stdio.h>
void f( int *sum, int x, int y )
{
*sum = x + y;
}
void g( int sum, int x, int y )
{
sum = x + y;
}
int main( void )
{
int x = 1, y = 2;
int sum;
sum = 0;
printf( "Before call of f sum = %d\n", sum );
f( &sum, x, y );
printf( "After call of f sum = %d\n", sum );
sum = 0;
printf( "Before call of g sum = %d\n", sum );
g( sum, x, y );
printf( "After call of g sum = %d\n", sum );
}
The program output is
Before call of f sum = 0
After call of f sum = 3
Before call of g sum = 0
After call of g sum = 0
The first function, function f. accepts the argument sum by reference that is using a pointer to sum. Thus after the function call the variable sum was changed.
The second function, function g, accepts the argument sum by value that is the function deals with a copy of the argument. Thus any changes of the copy do not influence on the value of the original argument.
In C++ apart from this meaning of the words "pass by reference" in the frames of C there is additional meaning because C++ introduced the notion of references like special kind of declarators and correspondingly defined the notion of the reference type.
Thus in C++ you can one more possibility to pass a value by reference. You may use a reference type. For example you could define a function for the example above the following way
void f( int &sum, int x, int y )
{
sum = x + y;
}
In this case as the argument is passed by reference that is the corresponding parameter type is a reference type then the function will deal with the original argument instead of its copy.
.

what's the difference between int (* f [])(); and int f[]();

i find this in Pointers on C
int f[](); /* this one is illegal */
and:
int (* f [])(); /* this one legal. */
i really want know what's the usage of the second one.
thank you.
The second example is quite valid, if you use initialization block. For example:
#include <stdio.h>
int x = 0;
int a() { return x++ + 1; }
int b() { return x++ + 2; }
int c() { return x++ + 3; }
int main()
{
int (* abc[])() = {&a, &b, &c};
int i = 0,
l = sizeof(abc)/sizeof(abc[0]);
for (; i < l; i++) {
printf("Give me a %d for %d!\n", (*abc[i])(), i);
}
return 0;
}
I'm not sure if the second example is legal, since the size of the function array is not known, but what it is supposed to be is an array of function pointers, and here is a possible example of usage if the size would be known:
int a()
{
return 0;
}
int main(int argc ,char** argv)
{
int (* f [1])();
f[0] = a;
}
int f[](); // this is illegal because of you can't create array of functions . It's illegal in C
But second is legal
int (* f [])(); It says that f is an array of function pointers returning int and taking unspecified number of arguments
int f[](); /* this one is illegal */
That's trying to declare an array of functions, which is impossible.
int (* f [])(); /* this one NOT legal, despite what the OP's post says. */
That's trying to declare an array of function pointers, which would be perfectly legal (and sensible) if the array size were specified, e.g.:
int (* f [42])(); /* this one legal. */
EDIT: The type int (* f [])() can be used as a function parameter type, because for function parameter types, array-to-pointer conversion takes place immediately, meaning we don't ever need to specify the dimension of the innermost array of a (possibly multidimensional) array:
void some_func(int (* f [])()); /* This is also legal. */

Passing two-dimensional array to a function by refrence (C Programming) [duplicate]

This question already has answers here:
Manipulate multidimensional array in a function
(4 answers)
Closed 8 years ago.
I'm learning pointers, and gotten stuck for an hour now, with this code,
#include <stdio.h>
int determinant(int **mat) /* int mat[3][3] works fine.. int *mat[3] doesn't.. neither does int *mat[] */
{
int det;
int a=*(*(mat+0)+0); // printf("\n%d",a);
int b=*(*(mat+0)+1); // printf("\n%d",b);
int c=*(*(mat+0)+2); // printf("\n%d",c);
int d=*(*(mat+1)+0); // printf("\n%d",d);
int e=*(*(mat+1)+1); // printf("\n%d",e);
int f=*(*(mat+1)+2); // printf("\n%d",f);
int g=*(*(mat+2)+0); // printf("\n%d",g);
int h=*(*(mat+2)+1); // printf("\n%d",h);
int i=*(*(mat+2)+2); // printf("\n%d",i);
det = a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g);
return det;
}
int main()
{
int mat[3][3];
int i,j;
printf("Enter the 3 X 3 matrix:\n\n");
for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
scanf("%d",*(mat+i)+j);
}
}
printf("\nThe determinant of the given 3 X 3 matrix is %d",determinant(mat));
return 0;
}
I don't think anything is wrong with the function call. Maybe the problem is while accepting the arguments. Idk, isn't mat a pointer to an 1-dimensional array, which would again be a pointer to the array element, making mat a pointer to a pointer?
When I print some text at places (just to check), i find that the execution goes till after int det in the function, and the program crashes in the next step.
mat [3][3] works well, but i wanna use some * there, because as i said, i'm 'learning'..
Please help!
Thanks :)
The correct prototype for your function is
int determinant(int mat[][3]);
or
int determinant(int (*mat)[3]);
(both are equivalent because of a special rule for arrays as function arguments)
Then you can simply access your matrix elements with something like mat[i][j].
This is because 2 dimensional array and pointer to pointer are not same.
No matter how much dimension does an array have, its 1 dimensional in actual memory. So we can access it serially.
#include <stdio.h>
#include <conio.h>
int determinant(int *matrix1stMember)
{
int a, b, c, d, e, f, g, h, i;
a = *(matrix1stMember + 0);
b = *(matrix1stMember + 1);
c = *(matrix1stMember + 2);
d = *(matrix1stMember + 3);
e = *(matrix1stMember + 4);
f = *(matrix1stMember + 5);
g = *(matrix1stMember + 6);
h = *(matrix1stMember + 7);
i = *(matrix1stMember + 8);
return ( a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g) );
}
int main()
{
int matrix[3][3]; // int matrix[y][x]; not [x][y]
int i, j;
printf("\nEnter 3x3 Matrix : ");
for(j = 0; j < 3; j++)
{
for(i = 0; i < 3; i++)
{
scanf("%d", &matrix[j][i]);
}
}
// call function determinant(int*) using first member of array
printf("\nDeterminant = %d", determinant(&matrix[0][0]));
getch();
return 0;
}
If we have to access via row and column then we can do following
data = *(_1stMemberofArray + rowIndex*totalColumn + columnIndex);
For Example,
data = matrix[2][1];
where datatype of matrix is
int matrix[3][3];
is identical to.
data = *(matrixPointer + 2*3 + 1);
where 3 is total column 2 is row(vertical or y) and 1 is column(horizontal or x).
and datatype of matrixPointer is,
int* matrixPointer;
and it should point to first member of matrix;
2D array dont decay to pointer to pointer. You can decay them to pointers so your code should look like
int determinant(int *mat) {
int det;
int a=*((mat+0)+0); // printf("\n%d",a);
int b=*((mat+0)+1); // printf("\n%d",b);
int c=*((mat+0)+2); // printf("\n%d",c);
int d=*((mat+1*3)+0); // printf("\n%d",d);
int e=*((mat+1*3)+1); // printf("\n%d",e);
int f=*((mat+1*3)+2); // printf("\n%d",f);
int g=*((mat+2*3)+0); // printf("\n%d",g);
int h=*((mat+2*3)+1); // printf("\n%d",h);
int i=*((mat+2*3)+2); // printf("\n%d",i);
det = a*(e*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g);
return det;
}
The above code is just for illustration, showing how 2-D array decays to 1-D array.
When you try to access the array using braces like a[2][1] then compiler does is unfolding for you. By unfolding I mean, the multiplication by sizeof(type) (as shown above multiply by 3). So if you decaying to 1-D you have to do it yourself.
One more thing to add, always pass the size of the dimension to the function who is has to tread the 1-D array as 2-D. like
int determinant(int *mat, int cols, rows);
Edit 1:
Just to add that #JensGustedt ans is also ok if you want to keep the arrays intact across function calls.
The correct signature for the function would be
int determinant(int mat[][3])
or
int determinant(int (*mat)[3])
In the context of a function parameter declaration, T a[] and T *a are exactly equivalent.
With either option, you can subscript mat normally in the function as you would in main:
int a = mat[0][0];
int b = mat[0][1];
...
Since a subscript operation implicitly dereferences the pointer (a[i] == *(a + i)),
you don't have to do the explicit dereference dance, making your code easier to read and understand (and potentially faster; I've seen some compilers generate more instructions for *(*(a + i) + j) than a[i][j], but don't rely on that being true everywhere).
Remember that when an expression of "N-element array of T" appears in most contexts, it is converted to an expression of type "pointer to T" and its value is the address of the first element in the array. Since the expression mat in the call to printf has type "3-element array of 3-element arrays of int", it is replaced with an expression of type "pointer to 3-element array of int".
If we pass a multidimensional array to a function:
int a2[5][7];
func(a2);
We can not declare that function as accepting a pointer-to-pointer
func(int **a) /* WRONG */
{
...
}
The function ends up receiving a pointer-to-an-array, not a pointer-to-a-pointer.

Resources