I'm writing a program that can modify rows and cols from a function of a function. I don't understand how to do pointer of a pointer.
void changeNum(int*setRows, int *setCol)
{
changeNum2(*setRows,*setCol);
}
void changeNum2(int*setRows, int *setCol)
{
*setRows=5;
*setCol=5;
}
int main() {
int*row=10;
int* col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
First
int*row=10;
int* col=10;
This is wrong. Assigning hardcoded address. You don't want this
int row=10;
int col=10;
How to get the address of the row and col?
&row and &col.
How to pass it to function?
Call it, changeNum(&row,&col);
void changeNum(int*setRows, int *setCol)
{
...
}
How to pass pointer to pointer?
void changeNum(int*setRows, int *setCol)
{
chnageNum2(&setRows, &setCol);
}
ChangeNum2 how it would change value?
void chnageNum2(int **setRows, int **setCol){
**setRows = 110;
**setCol = 110;
}
Can we do the same change using changeNum() only?
Yes we can do that.
void changeNum(int*setRows, int *setCol)
{
*setRows = 110;
*setCol = 110;
}
Definitely check this. Grab a book. It will help a lot.
The complete code will be
void changeNum(int*setRows, int *setCol)
{
changeNum2(&setRows,&setCol);
}
void changeNum2(int**setRows, int **setCol)
{
**setRows=5;
**setCol=5;
}
int main(void) {
int row=10;
int col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
#include <stdio.h>
void changeNum(int*, int*);
void changeNum2(int*, int*);
void changeNum(int* setRows, int *setCol) {
changeNum2(setRows,setCol);
}
void changeNum2(int* setRows, int *setCol) {
*setRows=5;
*setCol=5;
}
int main() {
int row=10;
int col=10;
changeNum(&row, &col);
printf("%d %d\n", row, col);
return 0;
}
It takes sometime to grasp that every C function parameter is passed by value. So you can safely pass setRows pointer to the second function simply by its value.
Also, it's necessary to declare previously the function changeNum2, I've included the declaration without parameter names to clarify it's possible.
I strongly recommend reading this book: https://en.wikipedia.org/wiki/The_C_Programming_Language, specially chapter 5 (Pointers and arrays).
You can find a PDF copy easily. It's where I finally learned this concept.
Related
I understand how to pass a 2D array to a function in C, but I would like to have the function update the original structure rather than a copy of it. How would I go about this? Why does the method I use create a copy of the structure - I was under the impression it was another syntax equivalent to using a pointer?
Thanks for any help. I've included code snippets underneath:
Declaring the variables
int R[rowsize][colsize], G[rowsize][colsize], B[rowsize][colsize];
int Rnew[rowsize][colsize], Gnew[rowsize][colsize], Bnew[rowsize][colsize];
Initialising the function
void blur(int rowsize, int colsize, int R[][428], int G[][428], int B[][428], int Rnew[][428], int Gnew[][428], int Bnew[][428]){
. . .
}
NB: Within this function, Rnew, Gnew and Bnew should be updated - each are a 2D array. I would like this to be done without returning anything.
Calling the function
blur(rowsize, colsize, R, G, B, Rnew, Gnew, Bnew)
You may try this way..
# include <stdio.h>
#define rowsize 3
#define colsize 3
int main()
{
int R[rowsize][colsize]={1,2,3,4,5,6,7,8,9};
int Rnew[rowsize][colsize];
copy_from_R_to_Rnew(R,&Rnew);
int i,j;
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++){
printf("\t %d",Rnew[i][j]);
}
printf("\n");
}
return(0);
}
void copy_from_R_to_Rnew(int *R,int *Rnew)
{
int i,j;
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++){
*(Rnew+i*colsize+j) = *(R+i*colsize+j);
}
}
}
this code allocates a matrix by means of a series of function calls, but when i print it, it return a segmentation fault error.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void mat_init(int** matx);
void pp_init(int** matx);
void p_init(int** matx);
void mat_fill(int** matx);
void mat_print(int** matx);
int main(void)
{
srand((unsigned)time(NULL));
int** matrix;
mat_init(matrix);
mat_print(matrix);
return 0;
}
void mat_init(int** matx)
{
pp_init(matx);
}
void pp_init(int** matx)
{
matx=malloc(4*sizeof(int*));
p_init(matx);
}
void p_init(int** matx)
{
for(int i=0;i<4;i++)
{
*(matx+i)=malloc(4*sizeof(int));
}
mat_fill(matx);
}
void mat_fill(int** matx)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
*(*(matx+i)+j)=rand()%5;
}
}
//mat_print(matx);
}
void mat_print(int** matx)
{
printf("The matrix is:\n");
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf("%1i|",*(*(matx+i)+j));
}
puts("");
}
puts("");
}
note that this happens only if i print the matrix using mat_print() int the main, if i use it in the function mat_fill() it works correctly, showing that it's been properly initialized.
What's the problem?
Essentially what you're doing is this:
void foo(int a);
{
a = 6;
}
int main()
{
int a = 3;
foo(a);
printf("a = %d\n", a); // expecting this to print 6
return 0;
}
Everything in C is pass by value, so that means anytime a parameter is passed to a function, a local copy of it is made in that function, and its scope exists only in that function; there is no exception for pointers. If I have this code instead:
void foo (int* ap2)
{
// there are now 2 pointers in memory that point to the same thing (main's a), namely
// ap2 on this stack frame and ap1 in the previous stack frame.
*ap2 = 6;
// ap2 is local to this function, but it _points_ to the same thing as
// ap1, so when we dereference it, changes to _what it points to_ are seen
// outside of this function. But once we return from this function, ap2
// ceases to exist
}
int main()
{
int a = 3;
int* ap1 = &a;
foo(ap1);
printf("a = %d\n", a); // now this prints 6
return 0;
}
If you want to manipulate main's matx in a function, then you need to pass a pointer to it and dereference it in that function in order to modify what it points to.
void foo (int*** matxp)
{
// matxp now points to matx in main
// dereference it here
*matxp = malloc(4 * sizeof(int*));
}
int main()
{
int** matx;
foo(&matx); // pass the address of matx here, which is an int*** type
....
// don't forget to clean up everything
return 0;
}
But as I said in the comments, I've rarely/never seen 3 star pointers. Instead you could just return the value
int** foo()
{
matxp = malloc(4 * sizeof(int*));
return matxp; // this will return NULL if malloc failed
}
int main()
{
int** matx = foo();
....
// do work, cleanup
return 0;
}
You need to do this:
int** mat_init(int** matx);
int** pp_init(int** matx);
int main(void)
{
matrix=mat_init(matrix);
}
int** mat_init(int** matx)
{
return pp_init(matx);
}
int** pp_init(int** matx)
{
matx=malloc(4*sizeof(int*));
p_init(matx);
return matx;
}
I omitted some lines that I didn't change. Another option is this:
void mat_init(int*** matx);
void pp_init(int*** matx);
int main(void)
{
mat_init(&matrix);
}
void mat_init(int*** matx)
{
pp_init(matx);
}
void pp_init(int*** matx)
{
*matx=malloc(4*sizeof(int*));
p_init(*matx);
}
Another thing: You're using the value 4 on a lot of places. That's dangerous. use a constant instead.
#define MAT_SIZE 4
void mat_fill(int** matx) {
for(int i=0;i<MAT_SIZE;i++) {
for(int j=0;j<MAT_SIZE;j++)
I am a Beginner in Functions.I wanna integrate that Functions in my main program. The program should scan a int number and then square it(sum=b*b). Then the program should output the result.
#include <stdio.h>
#include <stdlib.h>
void funktion(int);
void out(int);
int main(int)
{
int sum,b,v,w,z;
{
funktion();
calculator();
out();
printf("%i",sum);
}
return 0;
}
void funktion(int v)
{
printf("Enter any number that is to be squared!");
}
void calculator(int w) //calculate b*b
{
scanf("%i",&b);
sum=b*b;
}
void out(int z)
{
printf("Sum:");
}
Please give me some tips. ;)
Thx & Best regards!
Are you looking for this kind of solution: i just made little changes. you may need to do some initializing things if u gonna use this code
#include <stdio.h>
#include <stdlib.h>
void funktion(int);
void out(int);
int main()
{
int sum,b;
{
printf("Enter any number that is to be squared!");
scanf("%i",&b);
sum = funktion(b);
out(sum);
}
return 0;
}
int funktion(int b)
{
return b*b;
}
void out(int sum)
{
printf("Sum:%d",sum);
}
void funktion(int);
void out(int);
These two functions need not contain any arguments as you declared to be int's, because you are not performing any computation on sum, since they are just prints inside those functions.
So make them as,
void funktion(void);
void out(void);
and call those routines as,
funktion();
out();
void funktion(int)
{
printf("Enter any number that is to be squared!");
}
void out(int)
{
printf("Sum:");
}
to call these functions you are passing some value so you receive them with parameters.
void funktion(int a)
{
printf("Enter any number that is to be squared!");
}
void out(int b)
{
printf("Sum:");
}
You can make use of the passed value in functions using these variables, a nd b in corresponding functions.
If you dont want to access those passed values in the called functins then you dont need to pass the value. So change the functions to receive nothing, it can be
#include <stdio.h>
#include <stdlib.h>
void funktion();
void out();
int main()
{
int sum,b;
{
funktion();
scanf("%i",&b);
sum=b*b;
out();
printf("%i",sum);
}
return 0;
}
void funktion()
{
printf("Enter any number that is to be squared!");
}
void out()
{
printf("Sum:");
}
make the call to function without passing arguments. you can even specify void as type to indicate that function doesn't take any parameters.
To calculate in other function and return the value use return statement.
int calculator() //calculate b*b
{
scanf("%i",&b);
sum=b*b;
return sum;
}
change the function call statement to,
sum=calculator();
This is giving me a segfault at the memset and I have no idea why, I am going to a specific index of a 2D array, this should give me a char pointer and allow me to use memeset.
void test(char** test)
{
int i;
for(i=0;i<20;i++)
{
memset(test[i],0,sizeof(char)*1);
return;
}
}
int main()
{
char thing[20][20];
int i;
for(i=0;i<20;i++)
{
memset(thing[i],0,sizeof(char)*20);
}
test(thing);
return 0;
}
Your parameter declaration is incorrect, it should be:
void test(char test[20][20])
or:
void test(char test[][20])
I am slowly learning how to program generic functions in C and get into trouble now and so often. I am making a program that makes a union of two arrays, in this implementation two int arrays. The first problem, which also leads to the second one, is that the compareints (function) does not access one of the passed arguments (void *): I can't figure out why? I been staring at the screen for to long time now...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//makes union of two generic arrays and eliminates duplicates if there are some...
void **
unite(int (*comp)(void *f, void *s), void **first, void **second, int f_size, int s_size, int bytes, int *x)
{
int i;
void **arr=malloc(bytes*(f_size+s_size));
for(i=0; i<f_size+s_size; i++)
{
/* first bigger */
if(((*comp)(*first, *second))>0)
{
*(arr+i)=*(first++);
}
/* second bigger */
else if(((*comp)(*first, *second))<0)
{
*(arr+i)=*((second++));
}
/* equal => just one copy */
else
{
*(arr+i)=*(first++);
second++;
}
}
*x=i;
return arr;
}
int
compareints(void *first, void *second)
{
if(*((int *)first)>*((int *)second)) //can't access the memoryloc in second...
return 1;
else if(*((int *)first)<*((int *)second))
return -1;
else
return 0;
}
int main(int argc, const char * argv[])
{
int arr[10]={1, 2, 4, 12, 22, 29, 33, 77, 98};
int arr2[5]={3, 5, 7, 8, 9};
void **first=malloc(sizeof(int *)*10);
void **second=malloc(sizeof(int *)*5);
//make pointers to static arrays in dynamic arrays
int f_ind, s_ind;
for(f_ind=0; f_ind<10; f_ind++)
first[f_ind]=&arr[f_ind];
for(s_ind=0; s_ind<5; s_ind++)
second[s_ind]=&arr2[s_ind];
int i;
//make union of the two arrays and print out the result
void **ret=unite(&compareints, first, second, 10, 5, sizeof(int), &i);
for(int k=0; k<i; k++)
printf("%d ", *((int *)ret[k]));
return 0;
}
Why can't function access generic parameter ?
Simple answer to this question is function can access but further manipulation on void * is not possible.
Elements are accessed using pointer arithmetic (which needs size of individual element) since the pointer which is void * pointing to the address you passed but doesn't know about the size of each field in that array or memory location. so accessing or dereferencing will lead you to Undefined Behaviour.
If you want to access each element of that type inside the function then , pass the size of individual element to that function and on that basis make pointer to that same type , then access using new pointer of that type.
For more read this
I tried an approach thanks to #WhozCraigs post about the index going out of bounds. So I made some small mods and now the program does what it intends to.
void **
unite(int (*comp)(void *f, void *s), void **first, void **second, int f_size, int s_size, int bytes, int *x)
{
int i;
int f_ind=0, s_ind=0;
void **arr=malloc(bytes*(f_size+s_size));
for(i=0; i<f_size+s_size; i++)
{
/* first bigger */
if(((*comp)(*first, *second))>0)
{
s_ind++;
if(s_ind<s_size)
*(arr+i)=*(second++);
else
{
f_ind++;
if(f_ind<f_size)
*(arr+i)=*(first++);
else
break;
}
}
/* second bigger */
else if(((*comp)(*first, *second))<0)
{
f_ind++;
if(f_ind<f_size)
*(arr+i)=*(first++);
else
{
s_ind++;
if(s_ind<s_size)
*(arr+i)=*(second++);
else
break;
}
}
/* equal => just one copy */
else
{
f_ind++;
s_ind++;
if(f_ind<f_size && s_ind==s_size)
{
*(arr+i)=*(first++);
}
else if(f_ind==f_size && s_ind<s_size)
{
*(arr+i)=*(second++);
}
else
{
*(arr+i)=*(first++);
second++;
}
}
}
*x=i;
return arr;
}