I started learning C this week and here is the first difficulty I'm encountering with pointers.
I would like to test this function:
void ft_ultimate_div_mod(int *a, int *b)
{
int *tmp;
if (b != 0)
{
*tmp = *a % *b;
*a = *a / *b;
*b = *tmp;
}
}
But I can't figure out the main using pointers. My program is not printing anything with:
int main(void)
{
int *a;
int *b;
*a = 5;
*b = 3;
ft_ultimate_div_mod(a, b);
printf("%d", *a);
printf("%d", *b);
return (0);
}
What can I do? Thx!
For starters it does not make sense to declare the variable tmp as having the type int *. The variable is used to store an object of the type int so it has to have the type int. Otherwise you are using an uninitialized pointer with an indeterminate value that results in undefined behavior of the program.
Also as the variable is used in the compound statement of the if statement then it should be declared in the blco scope of the if statement.
These declarations in main
int *a;
int *b;
als do not make sense.
What you mean is the following.
#include <stdio.h>
void ft_ultimate_div_mod(int *a, int *b)
{
if ( *b != 0 )
{
int tmp = *a % *b;
*a = *a / *b;
*b = tmp;
}
}
int main(void)
{
int a = 10;
int b = 3;
ft_ultimate_div_mod( &a, &b );
printf( "%d %d\n", a, b );
return 0;
}
The function ft_ultimate_div_mod excepts its arguments by reference because it tries to change their original values.
You declare int *tmp in your function. That is a pointer to an int sized bit of memory that can store an int. You never point it anywhere however so *tmp = *a % *b; will do a mod of a an b and then crash when it stores it using an uninitialized pointer.
Change the *tmp to just tmp so then your code becomes:
void ft_ultimate_div_mod(int *a, int *b)
{
int tmp;
if (a && b)
{
tmp = *a % *b;
*a = *a / *b;
*b = tmp;
}
}
Related
I see a code which says the following.
typedef struct dummy
{
int a;
int b[100];
} dummy_t;
typedef struct dummya
{
int a;
int b;
} dummya_t;
void * getptr(){
// return a pointer of a memory
}
void function(){
dummya_t*dstptr = getptr();
dummy_t *srcpt = (dummy_t*)(dstptr->b);
}
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
Your code is not correct, you can not cast nor assign using pointers to objects of different types, for example:
struct a { int a, b; };
struct b { int a, b; };
are different objects even having the same members.
struct a x = {.a = 1, .b = 2};
struct b *y = &x; // wrong
I can see dummy_t srcpt = (dummy_t)(dstptr->b); meaning as a pointer
is pointing to another pointer but then *srcpt should be a double
pointer right? Like **srcpt
Your assumptions are not correct, a basic example using plain pointers to int:
#include <stdio.h>
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
int **ptr;
ptr = &a;
*ptr = &arr[1];
ptr = &b;
*ptr = &arr[0];
printf("a = %d b = %d\n", *a, *b);
return 0;
}
The output is:
a = 1 b = 2
a = 2 b = 1
As you can see, you use a double pointer (**ptr) when you want to change the contents of a or b (the address where it points to), a more useful example:
#include <stdio.h>
void swap(int **a, int **b)
{
int *temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
swap(&a, &b);
printf("a = %d b = %d\n", *a, *b);
return 0;
}
Same output:
a = 1 b = 2
a = 2 b = 1
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
No. That line means "treat the value of dstptr->b as though it were a value of type dummy_t *, and assign it to srcpt". It's not a pointer to a pointer.
The expression dstptr->b has type int, which cannot be directly assigned to a pointer type. (dummy_t *) is a cast, which tells the compiler to convert the type.
Like Vlad says in his comment, this code doesn't make any sense. It may compile, but just because it compiles doesn't mean it's right.
#include <stdio.h>
int *func()
{
int *a=malloc(5);
int *b=malloc(5);
for(int i=0;i<5;i++)
{
a[i]=i+1;
b[i]=i+5;
}
int *l= malloc(2);
l[0]=a;
l[1]=b;
//printf("%p %p ",l[0],l[1]);
return l;
}
int main()
{
int *k=func();
}
For the above code, how to return a,b arrays to main function?
Here after assigning values to the two arrays a and b i have given their adresses to new array l. Now after returning l to main, how to peint values of both the arrays a and b in main function?
You can do it the following way
struct Array
{
int a[5];
int b[5];
};
struct Array func( void )
{
struct Array a =
{
{1,2,3,4,5},
{1,2,3,4,5}
};
return a;
}
int main( void )
{
struct Array a = func();
//...
}
Another approach is to allocate arrays dynamically and return pointers to the allocated arrays from the function through output parameters. For example
#include <stdio.h>
#include <stdlib.h>
void func( int **a, size_t *n1, int **b, size_t *n2 )
{
*n1 = 5;
*a = malloc( sizeof( int ) * *n1 );
if ( *a != NULL )
{
int value = 1;
for ( size_t i = 0; i < *n1; i++ )
{
( *a )[i] = value++;
}
}
*n2 = 5;
*b = malloc( sizeof( int ) * *n2 );
if ( *b != NULL )
{
int value = 1;
for ( size_t i = 0; i < *n2; i++ )
{
( *b )[i] = value++;
}
}
}
int main(void)
{
int *a = NULL;
int *b = NULL;
size_t n1 = 0;
size_t n2 = 0;
func( &a, &n1, &b, &n2 );
//...
free( a );
free( b );
return 0;
}
void func(int **aa, int **bb)
{
static int a[5]={1,2,3,4,5};
static int b[5]={1,2,3,4,5};
*aa = a;
*bb = b;
}
void func2(int **aa, int **bb)
{
int *a = malloc(5 * sizeof(*a));
int *b = malloc(5 * sizeof(*b));
memcpy(a, (int []){1,2,3,4,5}, 5 *sizeof(*a));
memcpy(b, (int []){1,2,3,4,5}, 5 *sizeof(*b));
*aa = a;
*bb = b;
}
typedef struct
{
int a[5];
int b[5];
}mydata;
mydata func1(void)
{
mydata d = { .a = {1,2,3,4,5}, .b = {1,2,3,4,5}};
/* ... */
return d;
}
The second method is very expensive as the whole struct is being copied via (in most implementations) stack.
Example usage:
int main(void)
{
int *a,*b;
func2(&a, &b);
for(size_t i = 0; i < 5; i++)
{
printf("a[%zu] = %d, b[%zu]=%d\n", i, a[i], i, b[i]);
}
}
Functions in C can only return a single thing - that thing can be a struct with multiple attributes, but you cannot return and assign multiple independent items like you can in Python or Perl.
If the caller needs several independent items from the function, then you will need to use multiple output parameters - the caller must pass pointers to the things it wants the function to update, and the function updates the things being pointed to:
bool f( T *a, T *b ) // for some arbitrary type T
{
/**
* The *expressions* *a and *b have type T; writing to *a
* and *b in f is equivalent to writing to x and y in main.
*/
*a = new_T_value(); // writes a new value to the thing a points to
*b = another_new_T_value(); // writes a new value to the thing b points to
return some_boolean_value();
}
int main( void )
{
T x, y; // for some arbitrary type T
if ( f( &x, &y ) ) // f will write new values to x and y
do_something();
...
}
We can replace T with a pointer type P *, which gives us:
bool f( P **a, P **b ) // for some arbitrary type P
{
/**
* The expressions *a and *b have type P *; writing to *a and *b
* in f is equivalent to writing to x and y in main.
*/
*a = new_Pstar_value(); // writes a new value to the thing a points to
*b = another_new_Pstar_value(); // writes a new value to the thing b points to
return some_boolean_value();
}
int main( void )
{
P *x, *y; // for some arbitrary type T
if ( f( &x, &y ) ) // f will write new values to x and y
do_something();
...
}
The semantics are exactly the same - we want the function f to write new values to x and y, so we have to pass pointers to x and y as arguments. It's just in this case x and y already have a pointer type (P *), so we wind up passing pointers to pointers (P **).
Here’s the most straightforward way that requires the fewest changes to your existing code:
#include <stdio.h>
#include <stdlib.h> // need this for malloc
/**
* We want func to dynamically allocate arrays of int and
* assign the resulting pointers to *a and *b. We also want
* to dynamically allocate and return an array of int *.
*/
int **func( int **a, int **b)
{
/**
* malloc(5) allocates 5 *bytes*, not 5 ints.
* We need to multiply the number of things we
* want by the size of each thing.
*/
*a=malloc(5 * sizeof **a); // sizeof **a == sizeof (int)
*b=malloc(5 * sizeof **b);
for(int i=0;i<5;i++)
{
/**
* The postfix [] operator has higher precedence than the
* unary * operator; we don't want to dereference a[i] and
* b[i], we want to index into what a and b *point to*, so
* we must explicitly group the * operator with the variable
* name.
*/
(*a)[i]=i+1;
(*b)[i]=i+5;
}
/**
* Each l[i] holds a value of type int *,
* so l needs to have type int **
*/
int **l= malloc(2 * sizeof *l);
l[0]=*a;
l[1]=*b;
//printf("%p %p ",l[0],l[1]);
return l;
}
int main( void )
{
int *a, *b;
int **k=func( &a, &b );
}
I write a C program. I have 2 pointers *a and *b. Now, I impose *a = 20 and *b = 10. After that I impose a = b in subroutine but the value seem doesn't change. I expect that *a = 10 and *b = 10. Please help me find a solution for this. Thank you.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void Copy(int *a1, int *a2)
{
a1 = a2;
}
void Test()
{
// a = 20
int *a = (int *)malloc(sizeof(int));
*a = 20;
// b = 10
int *b = (int *)malloc(sizeof(int));
*b = 10;
Copy(a, b); // a = b
printf("\na = %d", *a);
printf("\nb = %d", *b);
}
int main(int argc, char *argv[]){
Test();
fflush(stdin);
printf("\nPress any key to continue");
getchar();
return 0;
}
Function arguments are passed by value. So inside the function Copy you are modifying a copy of the pointer not the original pointer you had in the Test function. So when you leave the Copy function the pointers outside are not modified.
Change the Copy to receive a int **, so you can change inside the value of pointers
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
And call the function in this way:
void Test() {
...
Copy (&a, &b);
...
}
If you want to assign the values, such that after the call of Copy *a == *b holds, then you'd have to change your function as follows:
void Copy(int *a1, int *a2)
{
*a1 = *a2;
}
If you want to assign the pointers, such that after the call of Copy a==b holds, then you have to pass a pointer to the pointers:
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
void Test() {
...
Copy (&a, &b);
...
}
Note that a==b also implies that *a == *b.
I'm trying my luck at this swap function but I'm having problems.
My hope is that the "new num1" should be swapped for the value of num2, and vice versa.
Can anyone shove me in the right direction?
#include <stdio.h>
void swap(int *a, int *b)
{
int temp = *a;
a = *b;
b = temp;
printf("Just checking if this badboy gets to the swapfunction.\n");
}
int main()
{
int num1 = 33;
int num2 = 45;
swap(&num1, &num2);
printf("A: %d\n", num1);
printf("B: %d\n", num2);
getchar();
return 0;
}
You need to deference the pointers:
int temp = *a;
*a = *b;
*b = temp;
Didn't your compiler warn you?
Some important things you should know about is:
int temp = *a; // Correct , temp stores value at the address of a
a = *b; //Incorrect, a is pointer that is used to hold address NOT values
Correction required is:
*a = *b; //Correct, now value at address of a is = value at address of b
Same mistake here also:
b = temp;//Incorrect, cause b is pointer used to hold address and NOT values
Correction required is
*b = temp;
I am trying to take a user entered array and swap the 0th value with the 7th, 8th value with the 3rd and the 0th with the 14th value. I have to use a function to swap which is where i think i messed up. When i compile it says to few arguments for function swap. also, its my 1st time using pointers so i wouldn't be surprised if there errors with that,. this is what i have, thanks!
#include <stdio.h>
void swap (int a[15], int *p, int *q, int *r ,int *s , int*t) {
int temp;
p = &a[0];
q = &a[7];
r = &a[8];
s = &a[3];
t = &a[14];
temp = *p;
*p = *q;
*q = temp;
temp = *r;
*r = *s;
*s = temp;
temp = *t;
*t = *p;
*p = temp;
}
int main (int argc, char *argv[]) {
int a[15], i;
printf(" Enter 15 integers: ");
for (i=0; i <15; i++)
swap(a);
printf(" Swapped array:\n %d", a[15]);
return 0;
}
Its not an error related to pointers.
You called swap() with one argument, like this swap(a);
And while defining it you have more then one arguments. Like
void swap (int a[15], int *p, int *q, int *r ,int *s , int*t) {
...
You do not need those extra arguments in the function definition.
Just change it to,
void swap (int a[15]) {
int temp;
int* p = &a[0];
int* q = &a[7];
int* r = &a[8];
int* s = &a[3];
int* t = &a[14];
...
A much better approach would be define a general function swap() and call it with proper required arguments multiple times when required.
void swap(int *p, int *q)
{
int tmp = *p;
*p = *q;
*q = tmp;
}
Call the above API something like
swap (&a[0], &a[7])
swap (&a[8], &a[3])
...
..