Trouble of pointers as function arguments - c

I have created a function that does the euclidean division in C and putting the quotient and remainder as function arguments.
code listing 1:
#include<stdio.h>
#include<stdlib.h>
void euclidean(int a, int b, int * q, int * r);
int main(int argc, char ** argv){
int * q;
int * r;
euclidean(5,4, q, r);
printf("q = %d, r = %d", *q, *r);
return 0;
}
void euclidean(int a, int b, int * q, int * r){
q = (int*)malloc(sizeof(int));
r = (int*)malloc(sizeof(int));
*q = a/b;
*r = a % b;
//printf("q = %d, r = %d", *q, *r); //this will show
return;
}
code listing 2:
#include<stdio.h>
#include<stdlib.h>
void euclidean(int a, int b, int * q, int * r);
int main(int argc, char ** argv){
int * q;
int * r;
euclidean(5,4, q, r);
printf("q = %d, r = %d", *q, *r);
return 0;
}
void euclidean(int a, int b, int * q, int * r)
{
*q = a / b;
*r = a % b;
//printf("q = %d, r = %d", *q, *r); //this won't show
return;
}
Both version aren't working. I compiled and ran the code on windows and the program is killed on runtime without printing anything (i.e. "q = 1, r = 4"). And my guess is if I had to compile and run it on linux, the terminal would gave me a "segmentation fault" error (not sure). I really don't see why it isn't working, especially with code listing 1. For code listing 2 one can argue that since the result of the operation are some sort of constant variable inside a function in which they were created, they could not be kept at the end of the function (I need confirmation on that too). Thanks

Keep It Simple, Stupid (there is such a principle).:)
#include<stdio.h>
#include<stdlib.h>
void euclidean(int a, int b, int * q, int * r);
int main(int argc, char ** argv){
int q;
int r;
euclidean(5,4, &q, &r);
printf("q = %d, r = %d", q, r);
return 0;
}
void euclidean(int a, int b, int * q, int * r)
{
*q = a / b;
*r = a % b;
}
If you want indeed to allocate memory in the function then the code will look like
#include<stdio.h>
#include<stdlib.h>
void euclidean(int a, int b, int * *q, int * *r);
int main(int argc, char ** argv){
int * q;
int * r;
euclidean(5,4, &q, &r);
printf("q = %d, r = %d", *q, *r);
free( q );
free( r );
return 0;
}
void euclidean(int a, int b, int * *q, int * *r){
*q = (int*)malloc(sizeof(int));
*r = (int*)malloc(sizeof(int));
**q = a/b;
**r = a % b;
}

You are not getting values for listing_2 because:-
void euclidean(int a, int b, int * q, int * r)
{
*q = a / b; <<<<<<<<<<<<<<<<<
*r = a % b;
//printf("q = %d, r = %d", *q, *r); //this won't show
return;
}
Neither you have allocated memory for q,r in main nor in euclidean. You were getting error as you are trying to deference a pointer not initialized to anything.

What you want is known as pass-by-reference, which allows the callee to modify the object the caller provides.
As C is purely pass-by-value, that is simulated with pointers:
The caller passes the address of the object the callee should modify, and the callee dereferences the received pointer to modify the intended target.
#include<stdio.h>
#include<stdlib.h>
void euclidean(int a, int b, int * q, int * r)
{
// Modify the target-objects q and r point to
*q = a / b;
*r = a % b;
}
int main() {
int q, r; // Not pointers, the objects themselves!
euclidean(5, 4, &q, &r); // Passing the addresses of q and r
printf("q = %d, r = %d", q, r);
}
No dynamic allocation at all.

Related

Which code would you prefer and why? Program to swap values using pointers [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
This is a program to swap two numbers using pointers.
#include<stdlib.h>
#include<stdio.h>
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
int main(int argc, char const *argv[])
{
int *a = (int *) malloc(sizeof(int));
int *b = (int *) malloc(sizeof(int));
*a =1;
*b =2;
printf("Nos are: %i %i\n", *a, *b);
swap(a,b);
printf("Swapped: %i %i\n", *a, *b);
free(a);
free(b);
return 0;
}
Would you prefer this or,
#include<stdlib.h>
#include<stdio.h>
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
int main(int argc, char const *argv[])
{
int a= 1;
int b= 2;
printf("Nos are: %i %i\n", a, b);
swap(&a,&b);
printf("Swapped: %i %i\n", a, b);
return 0;
}
Which one is better in terms of programming standards? or which one would you prefer? (pls give some theoretical explanation as well)
Output for both the codes are same i.e it swaps and returns 2 1
I would
prefer first case if I am swapping some heavy data, lets say some struct x, so we pass address of struct which is a fixed size depends on system.
prefer second case for normal data like int or char etc..
There is no need to allocate memory and free.
I would not prefer swap function using pointers.
This task is best done by the macros:
#include <stdio.h>
#define SWAP(a,b,type) do{type c__c__c; c__c__c = (a); (a) = (b); (b) = c__c__c;}while(0)
struct s
{
int a;
char x[100];
double w[100];
};
int main()
{
double a = 5.0, b = 6.0;
int c = 5, d = 6;
struct s x = {.a = 1},y = {.a = 2};
SWAP(a, b, double);
SWAP(c, d, int);
SWAP(x, y, struct s);
printf("%f %f\n", a, b);
printf("%d, %d\n", c, d);
printf("%d, %d\n", x.a, y.a);
return 0;
}
and the code will every efficient. You also do not have to write dozens of functions for every type.
Of course you can write "generic" swap function
void *swap(void *a, void *b, size_t size)
{
unsigned char temp[size];
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
return a;
}

Using Pointers In C swapping three numbers

#include <stdio.h>
int main() {
int a, b,c;
/* Input a and b */
scanf("%d %d %d", &a, &b,&c);
while(a != -1) {
int *x = &a;
int *y = &b;
int *z = &c;
printf("Original inputs: a:%d\tb:%d\tc:%d\n", a, b,c);
reorder(a,b,c);
swap(a,b);
printf("Rearranged inputs: a:%d\tb:%d\tc:%d\n\n", a, b,c);
break;
}
}
void reorder(int *x, int *y, int *z){
if(*x > *y)
{
int temp = *x;
*x = *y;
*y = temp;
}else if(*y > *z){
int temp = *y;
*y = *z;
*z = temp;
}else if(*x > *z){
int temp = *x;
*x = *z;
*z = temp;
}
}
void swap(int *px, int *py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
I am new to C and learning pointers am not sure how to implement pointers to swap 3 numbers in ascending order
This might give you a way to start:
#include <stdio.h>
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
void reorder(int* x, int* y, int* z) {
if (*x > *y) {
swap(x, y);
}
if (*y > *z) {
swap(y, z);
}
if (*z > *x) {
swap(z, x);
}
}
int main() {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
int *x = &a;
int *y = &b;
int *z = &c;
reorder(x, y, z);
}
You can use this code for your purpose :
#include <stdio.h>
void reorder(int *, int *, int *);
void swap(int *, int *);
void main()
{
int a, b, c;
printf("Enter three numbers : ");
while (scanf("%i %i %i", &a, &b, &c)==3)
{
reorder(&a, &b, &c);
printf("Now a is %d, b is %d and c is %d.\n\n", a, b, c);
printf("Enter three numbers : ");
}
}
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
void reorder(int* a, int* b, int* c) {
if (*c<*a&&*c<*b)
swap(a, c);
if (*b<*a&&*b<*c)
swap(a, b);
if (*c<*b)
swap(b, c);
}

Beginner C programming passing pointers to function is giving unpredicted result

I am learning C as a part of my curriculum, and I am still learning the concepts of pointers. The following example gives unpredicted results for me.
#include <stdio.h>
void Calculate(int *x, int *y, int *k, int *m) {
k = *x * *y;
m = *x + *y;
}
int main() {
int *k;
int *m;
int g = 10;
int h = 11;
Calculate(&g, &h, k, m);
printf("%d\n", m);
printf("%d", k);
}
Each execution is giving me different results, like
-1155180448
0
or
253276384
0
or
591649904
0
but if I change the code to
#include <stdio.h>
void Calculate(int *x, int *y, int *k, int *m) {
*k = *x * *y;
*m = *x + *y;
}
int main() {
int k;
int m;
int g = 10;
int h = 11;
Calculate(&g, &h, &k, &m);
printf("%d\n", m);
printf("%d", k);
}
it prints the correct values like
21
110
Isn't using int *k; int *m; and passing it to a function as somefunc(k, m) the same as int k; int m; somefunc(&k, &m)?
Kindly explain what is wrong here.
Thank you.
The function should be:
void Calculate(int *x, int *y, int *k, int *m) {
*k = *x * *y;
*m = *x + *y;
}
*k means an int stored in memory being pointed to by k. You don't want to modify k, you want to modify what is stored in the space k points to.
Then you call like this:
int a, b;
int g = 10;
int h = 11;
Calculate(&g, &h, &a, &b);
You tell the Calculate function whereabouts in memory the variables a and b are which will hold the result of the calculation.
Note: I used different variable names because it is confusing to use the same name k for an int in one place, and k for an int * in another place. Another plan of course would be to use k,m in main and use pk or pm in the function (meaning "pointer to k", etc.)
Also you don't need to use pointers to pass g and h and in fact this is a bad idea, unless you are planning to change those in the function too.
If you really want to test this call Calculate(&g, &h, k, m); as in your first example, passing integers g and h and integer pointers *k and *m, first make sure that the pointers really point at something, so they can be treated likewise as addresses of integer variables by your Calculate() function, or whichever function of syntax alike.
#include <stdio.h>
#include <stdlib.h> //add this header for malloc
void Calculate(int *x, int *y, int *k, int *m) {
*k = *x * *y;
*m = *x + *y;
}
int main()
{
int *k = malloc(sizeof(int)); //initialize the pointer to point at something
int *m = malloc(sizeof(int)); //initialize the pointer to point at something
int g = 10;
int h = 11;
Calculate(&g, &h, k, m);
printf("%d\n", *m);
printf("%d\n", *k);
free(k); //free the space pointed to by pointers!
free(m);
return 0;
}
This is not a very practical solution (at least as your example is concerned), but is here only to show how you should treat your pointers as function arguments from within your caller function.

C program for sorting 3 random numbers , void reorder3(int a, int *b, int **c);

This code is working but its not exactly what I want. Is anyone have any idea how to make it correct and without q sort?. The idea is to understand how to use pointers.
The three numbers should be random between -3 and 12. The code below is something similar, and the closest I have found. Any help would be much appreciated. Thanks in advance!!.
#include <stdio.h>
#include <stdlib.h>
//functions
int compare(const void *a, const void *b)
{
const int *ia = a;
const int *ib = b;
if (*ia < *ib)
return -1;
else if (*ia > *ib)
return +1;
return 0;
}
//qsort function
void sort3(int *a, int *b, int *c)
{
int temp[3];
temp[0] = *a;
temp[1] = *b;
temp[2] = *c;
qsort(temp, 3, sizeof(int), &compare);
*a = temp[0];
*b = temp[1];
*c = temp[2];
}
//random function
int rand_int(int a, int b)
{
return rand()%(b-a+1)+a;
}
int main(void)
{
//declaration of variables
int a,b,c;
int rand_int(int a, int b);
srand(time(0));
a = rand_int(-3,12);
b = rand_int(-3,12);
c = rand_int(-3,12);
printf("%i %i %i\n", a, b, c);
sort3(&a, &b, &c);
printf("%i %i %i\n", a, b, c);
return 0;
}
You don't need the compare() function if you don't want to use qsort().
You can rewrite sort3() like this:
void compare_and_swap(int *a, int *b) {
int t;
if (*a > *b) {
t = *a;
*a = *b;
*b = t;
}
}
void sort3(int *a, int *b, int *c) {
compare_and_swap(a, b);
compare_and_swap(a, c);
compare_and_swap(b, c);
}
This is actually a "bubble sort".
This is a lot of trouble to go for to sort 3 integers. Use if statements.
If the goal is actually to understand pointers, they seem intimidating but they're not so bad. Basically, they're a number that happens to be an address. You can manipulate like them numbers, but if you dereference them (with *), you can get the value there. This cuts both ways, though, because there's not much stopping you from dereferencing a value - which probably crashes your program (or more scarily, maybe not).
As long as you keep in mind what's an address and what's a value, you should be OK.

how to make a array of pointer to call func pointer?

i have code to array of func pointer
#include <stdio.h>
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
printf("Enter two numbers: ");
scanf("%d %d", &i, &j);
printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n");
do {
printf("Enter number of operation: ");
scanf("%d", &op);
} while(op<0 || op>3);
result = (*p[op]) (i, j);
printf("%d", result);
return 0;
}
int sum(int a, int b)
{
return a + b;
}
int subtract(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
if(b)
return a / b;
else
return 0;
}
code for array of pointer to function:
#include <stdio.h>
int sum(int, int);
int product(int, int);
int subtract(int, int);
int main()
{
int i = 0;
int a = 10;
int b = 5;
int result = 0;
int (*pfun[3])(int, int);
pfun[0] = sum;
pfun[1] = product;
pfun[2] = subtract;
for( i = 0 ; i < 3 ; i++)
{
result = pfun[i](a, b);
printf("\nresult = %d", result);
}
result = pfun[1](pfun[0](a, b), pfun[2](a, b));
printf("\n\nThe product of the sum and the subtract = %d\n",result);
}
int sum(int x, int y)
{
return x + y;
}
int product(int x, int y)
{
return x * y;
}
int subtract(int x, int y)
{
return x - y;
}
now how to combine this two program. such that array of pointers pointing to func pointers and the func pointers may have different number of args? any suggestion.
You not only need to store function pointers with a variable number of arguments (that is not very difficult, you could use a union for instance), but you also need to make sure you call the functions with the correct argument, and that is a bit trickier given your design.
I suggest to use a stack instead. All your functions would only take the stack as an argument:
void sum(stack_t *stack);
void subtract(stack_t *stack);
void product(stack_t *stack);
And your array could be declared this way:
typedef void callback_t(stack_t *);
callback_t *p[] =
{
sum,
subtract,
product,
/* ... */
};
Then for instance sum would be implemented as such:
void sum(stack_t *stack)
{
if (depth(stack) < 2)
perror("Not enough arguments in stack!");
int b = popstack(stack);
int a = popstack(stack);
int c = a + b;
pushstack(stack, c);
}
But unary minus would be implemented this way:
void neg(stack_t *stack)
{
if (depth(stack) < 1)
perror("Not enough arguments in stack!");
int a = popstack(stack);
pushstack(stack, -a);
}
Each function decides how many arguments they need. The caller does not need to know.

Resources