Why can't I pass and edit this array to a function? - c

My previous question was answered but I have another in the same vein. Why does the code not work when I try to use a multi-dimensional array?
void change(int *);
int main(void){
int array[1][2] = {2};
printf("%d", array[1][2]);
change(array);
printf("%d", array[1][2]);
}
void change(int *array){
array[1][2] = 4;
}

You need to use asterisks for parameter at the time of declaration and definition.
For making array[0]=4, you only need to assign 4 to array[0] without asterisk. So your code should be:
void change(int *);
int main(void){
int array[1] = {2};
printf("%d", array[0]);
change(array);
printf("%d", array[0]);
}
void change(int *array){
array[0] = 4;
}

enter code here void change(int*);
int main(void){
int array[1] = {2};
printf("%d\n", array[0]);
change(array);
printf("%d\n", array[0]);
}
void change(int* array)
{
array[0] = 4;
*(array + 0) = 4;
}
don't put '&' in array. it is pointer. so you must change your function "change(int ...) to change(int* )"
and to change array[0] you don't need to put * on array. it's an array!. or to use * . then you must add n-th element number.

C language uses pass by value.
So, You have to receive the address of array as argument.
void change(int *, int);
int main(void) {
int array[3] = { 1, 2, 3 };
printf("%d", array[1]);
change(array, 1);
printf("%d", array[1]);
}
void change(int *array, int index) {
*(array+index) = 4;
}
For the multi dimension, You should pass a size of column.
I made 2 samples as change and change2.
I think you can understand change well.
But, In case of change2, array has a head address of memory in array[2][3] and it has 6 integers by 2x3. So, you can calculate.
void change(int array[2][3], int, int, int);
void change2(int *, int, int, int, int);
int main(void) {
int array[2][3] = { { 1, 2, 3 }, {4, 5, 6} };
printf("%d", array[1][1]);
change(array, 1, 1, 10);
printf("%d", array[1][1]);
change2((int *)array, 3, 1, 1, 20);
printf("%d", array[1][1]);
}
void change(int array[2][3], int row, int col, int value) {
array[row][col] = value;
}
void change2(int *array, int size_col, int row, int col, int value) {
*(array + row*size_col + col) = value;
}

Related

How to retrieve array values in c from another function

Here's my code:
#include <stdio.h>
int func(int a[]);
int main()
{
int a[5] = {1, 2, 3, 4, 5};
a[] = func(a);
What changes should I make on the above line to get the new values in the array ?
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
}
int func(int a[])
{
for (i = 0; i < 5; i++)
{
a[i] = a[i] + 1;
}
return a;
}
Thanks in advance!
When you pass an array as an argument of a function, it is not a copy, in fact that argument decays to a pointer to the first element of the passed array, using int func(int a[]); is basically the same as using int func(int *a);, any changes made to the array inside the function will be permanent.
What changes should I make on the above line to get the new values in the array?
Given the above explanation, your function doesn't need to return a:
void func(int a[]) // as no return is needed, the return type should be void
{
for (int i = 0; i < 5; i++)
{
a[i] = a[i] + 1;
}
// no need to return a, it's permanently changed already
}
Consequently the assignment to a in main needs to be replaced by a simple function call:
int main()
{
int a[5] = {1, 2, 3, 4, 5};
func(a); //call the function
for (int i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
}
The output will be:
2 3 4 5 6

Pointer to pointer as a function parameter

I have the following code:
#include <stdio.h>
#include <stdlib.h>
int f(int x, int *py, int **ppz) {
int y, z;
**ppz += 1;
z = **ppz;
*py += 2;
y = *py;
x += 3;
return x + y + z;
}
int main(void) {
int c = 4;
printf("f(): %d\n", f(c, &c, &&c));
printf("c: %d\n", c);
return EXIT_SUCCESS;
}
How can I access **ppz correctly, because so I get an error message: "label 'c' used, but not defined".
An int** is a pointer to an int*. You need to create a variable of type int* to be able to pass a pointer to it somewhere. Here is what you should do:
int main(void) {
int c = 4;
int* pc = &c;
printf("f(): %d\n", f(c, pc, &pc));
printf("c: %d\n", c);
return EXIT_SUCCESS;
}
Refer #ikegami's answer for an explanation of the proper use of a pointer to a pointer.
You want to modify a variable of type int, so the parameter should be int *, not int **.
You'd use int ** if you wanted to modify a variable of type int * variable. That's not the case here.
For example,
void f(int **pp) {
*pp = malloc(10);
}
int main(void) {
int *p;
f(&p);
// ...
free(p);
}

How to allocate memory and assign values in a function for an array of pointers?

I am having trouble figuring out how to allocate memory for an array of pointers in a function. In this same function I am trying to initialize the arrays with values from another array. I have been trying different things for a while and I cannot figure out where I do and do not need.
#include <stdio.h>
#include <stdlib.h>
void allocate();
void print();
int main() {
int array_length = 10;
int array[array_length] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int **ascending;
int **descending;
allocate(&ascending, &descending, array, array_length);
print(&ascending, &descending, array, array_length);
}
void allocate(int ***ascending, int ***descending, int array[], int array_length) {
*ascending = (int **)malloc(array_length * sizeof(int *));
*descending = (int **)malloc(array_length * sizeof(int *));
int i, first_index = 0;
for (i = 0; i < array_length; i++) {
(*ascending)[i] = &(array[i]);
(*descending)[i] = &(array[i]);
}
}
void print(int **ascending, int **descending, int array[], int array_length) {
int i;
printf("\nAscending\tOriginal\tDescending\n\n");
for (i = 0; i < array_length; i++) {
printf("%d\t\t", ascending[i]);
printf("%d\t\t", array[i]);
printf("%d\t\t", descending[i]);
printf("\n");
}
printf("\n");
}
First of all, variable-size arrays cannot be initialized. You should use a MACRO for array_length.
Then, as per your function definition, the call to print() needs int ** as first two arguments, not int ***. Change the function call to
print(ascending, descending, array, array_length);
also, ascending[i] and descending[i], in this case, are of type int *, you need one more level of dereference to get the int.
That said,
void allocate();
void print();
are bad forward declarations. You should be using the exact signature of the functions for declaration and definition.
A sample working version may look like something
//gcc 4.9.3
#include <stdio.h>
#include <stdlib.h>
#define arraysize 10
void allocate(int ***ascending, int ***descending, int array[], int array_length);
void print(int **ascending, int **descending, int array[], int array_length);
int main(void) {
int array_length = arraysize;
int array[arraysize] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int **ascending;
int **descending;
allocate(&ascending, &descending, array, array_length);
print(ascending, descending, array, array_length);
return 0;
}
void allocate(int ***ascending, int ***descending, int array[], int array_length) {
*ascending = (int **)malloc(array_length * sizeof(int *));
*descending = (int **)malloc(array_length * sizeof(int *));
int i = 0;//, first_index = 0;
for (i = 0; i < array_length; i++) {
(*ascending)[i] = &(array[i]);
(*descending)[i] = &(array[i]);
}
}
void print(int **ascending, int **descending, int array[], int array_length) {
int i;
printf("\nAscending\tOriginal\tDescending\n\n");
for (i = 0; i < array_length; i++) {
printf("%d\t\t", *(ascending[i]));
printf("%d\t\t", array[i]);
printf("%d\t\t", *(descending[i]));
printf("\n");
}
printf("\n");
}

how to persist the pointer increment

I have the following code
void fun(int * d)
{
d+=1;
}
int main()
{
int * f=malloc(5);
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
fun(f);
printf("value : %d\n",*f);
return 0;
}
So, i pass an integer pointer to function and increment it there. I want that increment to persist when it returns to main.
When I print the value, The output is '0'. But I want the output to be '1' as I have incremented the value in function.
So, briefly, my question is, how to persist the changes made to a pointer?
Assuming you want to increment the pointer, not the value, you have two options:
recast the function to void fun(int ** d), use (*d)+=1; in the function body, and call using fun(&f);
recast the function to int* fun(int* d), and return the new value.
If you want to increase the value, then use (*d)+=1; in the function body.
You don't need the parentheses around *d: I've put them in for clarity.
You forgot * in d+=1;
When you pass that pointer you have access to f[0] with that approach:
Take a look here:
#include <stdio.h>
#include<stdlib.h>
void fun(int *d){
*d+=1;
}
int main(void){
int i;
int *f=malloc(5 * sizeof int);
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
printf("\n");
fun(f);
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
free(f);
return 0;
}
Output:
0 1 2 3 4
1 1 2 3 4
Or if you try to add +1 to all elements you can do something like this:
#include <stdio.h>
#include<stdlib.h>
int *fun(int *d, int len){
int i;
int *newArray = d;
int newValue = 1;
printf("\n");
for(i = 0; i < len; i++) {
newArray[i] += newValue;
}
return newArray;
}
int main(void){
int i;
int f[] = {0,1,2,3,4};
int *newArray;
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
printf("\n");
newArray = fun(f,5);
for(i=0;i<5;i++){
printf("%d ",newArray[i]);
}
return 0;
}
Output:
0 1 2 3 4
1 2 3 4 5
And by the way you forgot to free f.
You have to pass the address of the pointer, so:
void fun(int **val) {
*val++;
....
}
int main() {
...
fun(&f);
...
}

Nothing works - references, pointers

void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}

Resources