How to pass arrays to functions - c

I am trying to write a program which calculates some bags and weights. I wrote it without using functions but I have to use functions and I am really bad at it.
The code normally works, but I just can't implement it with functions. It stops working after printing array A, and just 0s when printing array B.
My code is:
#include <stdio.h>
#include <math.h>
int f1(int N);
int f2(int N);
int f3(int N, float A[20]);
int main(void)
{
int N;
f1(N);
return 0;
}
int f1(int N)
{
for(;;)
{
printf("Enter N(the number of bags) (Between 1 and 20): ");
scanf("%d", &N);
if (N < 1 || N > 20)
{
continue;
}
else
{
break;
}
}
f2(N);
}
int f2(int N)
{
float A[20];
int i;
for(i=0; i<N;i++)
{
printf("Enter the weight of the bag with potatoes %d: ", i+1);
scanf("%f", &A[i]);
}
printf("\n\nThe weights of the initial bags (the A array):\n");
for(i=0; i<N;i++)
{
printf("%.1f " ,A[i]);
}
f3(N, &A[20]);
}
int f3(int N, float A[20])
{
int i;
float B[10];
printf("\n\nNow we equalize the weights of bags.\n");
if (N%2 == 0)
{
for(i=0;i<N/2 ;i++)
{
B[i] = fabsf(A[i] - A[N-1-i]);
}
}
else
{
for(i=0;i<N/2 ;i++)
{
B[i] = fabsf(A[i] - A[N-1-i]);
}
B[N/2] = A[N/2];
}
if (N%2 == 0)
{
for (i=0; i<N/2; i++)
{
if (A[i] < A[N-1-i])
{
A[N-1-i] = A[i];
}
else
{
A[i] = A[N-1-i];
}
}
}
else
{
for (i=0; i<N/2; i++)
{
if (A[i] < A[N-1-i])
{
A[N-1-i] = A[i];
}
else
{
A[i] = A[N-1-i];
}
}
A[N/2] = 0;
}
printf("\nThe weights of the new bags (the B array):\n");
if (N%2 == 0)
{
for(i=0; i<N/2 ;i++)
{
printf("%.1f " ,B[i]);
}
}
else
{
for(i=0; i<N/2 ;i++)
{
printf("%.1f " ,B[i]);
}
printf("%.1f", B[N/2]);
}
printf("\nThe new weights of the initial bags (the A array):\n");
for(i=0;i<N;i++)
{
printf("%.1f ", A[i]);
}
}

To pass an array to a function just use its name.
f3(N, &A[20]);
should be
f3(N, A);

To pass an array or pointer as an argument when calling a function in C, you just need to pass it name, in your case,
f3(N, A);
Also, when declaring the function, the length of the array doesn't matter, because C performs no bounds checking for formal parameters. Although it will work this way, it is best to change
int f3(int N, float A[20])
to
int f3(int N, float A[])
or
int f3(int N, float* A)

Related

Do we have to create an even and an odd array?

How can we modify the following code (which initially asks the user for 10 numbers to be entered, get stored in an array, and printed on the screen) so that the even numbers are printed on the first line, and the odd on the second:
#include <stdlib.h>
#include <stdio.h>
int i,j;
int array_1[10];
int main() {
for(i=0;i<10;i++) {
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The elements of the array are: ");
for (j=0;j<10;j++) {
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
O(n) Solution:
you have to add odd numbers at the back of the array and add the even numbers at the front of the array and keep track of the indexes.
int array_1[10];
int main() {
int even = 0, odd = 10;
for (int i = 0; i < 10; i++) {
printf("Enter a number: ");
int inp;
scanf("%d", &inp);
if (inp % 2 == 0) {
array_1[even++] = inp;
} else {
array_1[--odd] = inp;
}
}
// even numbers
for (int i = 0; i < even; i++) {
printf("%i ", array_1[i]);
}
printf("\n");
// odd numbers
for (int i = 9; i >= odd; i--) {
printf("%i ", array_1[i]);
}
printf("\n");
return 0;
}
Since you asked, here is how I would do it. I suspect this may leave you with more questions than answers through.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#define NUMBERS_SIZE 10
typedef bool (*number_validator)(int num);
bool isEven(int num)
{
return (num & 1) == 0;
}
bool isOdd(int num)
{
return (num & 1) != 0;
}
void print(const char *title, int *array, int array_size, number_validator isValid)
{
printf("%s", title);
bool first = true;
for (int i = 0; i < array_size; ++i)
{
if (isValid(array[i]))
{
if (!first)
{
printf(", ");
}
printf("%d", array[i]);
first = false;
}
}
printf("\n");
}
int main()
{
int numbers[NUMBERS_SIZE] = { 0 };
for (int i = 0; i < NUMBERS_SIZE; i++)
{
printf("Enter a number: ");
scanf("%d", &numbers[i]);
}
printf("\n");
print("Even: ", numbers, NUMBERS_SIZE, isEven);
print(" Odd: ", numbers, NUMBERS_SIZE, isOdd);
return 0;
}
Demo on ideone
you can try this way.I have used binary AND(&) instead of MOD(%) as it is faster:
#include <stdlib.h>
#include <stdio.h>
int i,j;
int array_1[10];
int main()
{
for(i=0; i<10; i++)
{
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The Even elements of the array are: ");
for (j=0; j<10; j++)
{
if((array_1[j]&1) == 0)
printf("%d ", array_1[j]);
}
printf("\nThe Odd elements of the array are: ");
for (j=0; j<10; j++)
{
if((array_1[j]&1) != 0)
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
No need to create a new array. You can just go through it first checking for even numbers, and then again for odd numbers. Also, there's no need to declare i and j before using them. You can just declare them and initialize them in the for loop:
#include <stdlib.h>
#include <stdio.h>
int array_1[10];
int main() {
for(int i=0;i<10;i++) {
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The elements of the array are: ");
// Print even numbers
for (int j=0;j<10;j++) {
if(array_1[j] % 2 == 0)
printf("%d ", array_1[j]);
}
printf("\n");
// Print odd numbers
for (int j=0;j<10;j++) {
if(array_1[j] % 2 != 0)
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
Edit: As tadman suggested in the comment below, there's a better and cleaner way to do this kind of task. As you can see in the above example, I'm repeating 4 lines of code where only one character changes. This task could be abstracted into a function to reduce code repetition:
void printIfMod(int* arr, size_t array_size, int mod){
for (int j=0;j<array_size;j++) {
if(arr[j] % 2 != mod)
continue;
printf("%d ", arr[j]);
}
printf("\n");
Remember to add a function prototype before main if you place the function after main:
void printIfMod(int* arr, size_t array_size, int mod);
int main(){...}
Now, to print the numbers, call the method with modulo 0 to get even numbers, and 1 to get odd numbers:
// Print even numbers
void printIfMod(&array_1, 10, 0);
// Print odd numbers
void printIfMod(&array_1, 10, 1);
One last note, hard-coding array_size is not wise, and that goes for all arrays. I recommend using sizeof() to dynamically calculate the size of your array:
size_t size = sizeof(array_1) / sizeof(int);
// Print even numbers
void printIfMod(&array_1, size, 0);
// Print odd numbers
void printIfMod(&array_1, size, 1);

Why am I getting segmentation fault and how do I solve this?

C program for bubble sort using a minimum of 4 functions.(input,output,compute,main)
No global variables allowed.
No printf or scanf in compute.
No printf or scanf in main
Input should not call compute.
compute should not call output.
I haven't really understood pointers and functions.
#include <stdio.h>
void input(int* size, int* arr[])
{
printf("Enter the size of the array: ");
scanf("%d",size);
printf("Enter the elements of the array\n");
for(int i = 0;i < *size; i++)
{
scanf("%d", arr[i]);
}
}
void swap(int *x,int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void bubble_sort(int arr[100],int size)
{
for(int i = 0;i < size - 1;i++)
{
for(int j = 0;j < size - 1 - i;j++)
{
if(arr[j] > arr[j+1])
{
swap(&arr[j],&arr[j+1]);
}
}
}
}
void output(int size,int* arr)
{
printf("Sorted array\n");
for(int i = 0;i < size;i++)
{
printf("%d",arr[i]);
}
}
int main()
{
int* input_values[50];
int size;
input(&size, input_values);
bubble_sort(size,*input_values);
output(size, *input_values);
return 0;
}
No errors but showing segmentation fault.How do I solve this?
So your problem is here :
scanf(" %d", arr[i]);
You have to change this to :
scanf(" %d", &arr[i]);
This is the main problem, but there are a lot of others.
Also you have to change the order of parameters in
bubble_sort(size,*input_values);
to
bubble_sort(input_values,size);
and
output(size, *input_values);
to
output(size, input_values);
Also in order this to work at all i have changed the
scanf("%d", &arr[i]);
to
scanf(" %d", &arr[i]);
Actually your code is full of mistakes like the usage of scanf and the usage of pointers and arrays, the following is a workable version of you code see and compare:
#include <stdio.h>
void input(int* size, int arr[])
{
char chr;
printf("Enter the size of the array: ");
scanf( "%d%c", size, &chr );
printf("Enter the elements of the array\n");
for(int i = 0;i < *size; i++)
{
scanf("%d%c", &arr[i], &chr);
}
}
void swap(int *x,int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void bubble_sort(int* size,int arr[])
{
for(int i = 0;i < *size - 1;i++)
{
for(int j = 0;j < *size - 1 - i;j++)
{
if(arr[j] > arr[j+1])
{
swap(&arr[j],&arr[j+1]);
}
}
}
}
void output(int* size,int arr[])
{
printf("Sorted array\n");
for(int i = 0;i < *size;i++)
{
printf("%d",arr[i]);
}
}
int main()
{
int input_values[50];
int s = 0;
int* size = &s;
input(size, input_values);
bubble_sort(size,input_values);
output(size, input_values);
return 0;
}

function for multiple occurrences in linear search using pointer

This is the code i wrote for multiple occurrences in linear search.Can you please help me point out the mistake ? I want the function to store multiple values in the pointer array and then later to print the array
#include <stdio.h>
void linearsearch(int n,int a[n],int x,int count,int *b[count])
{
count=0;
int i;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
b[j]=i;
j++;
}
}
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int x;
scanf("%d",&x);
int count;
int *b[count];
linearsearch(n,a,x,count,b);
for(i=0;i<count;i++)
{
printf("%d",*b[i]);
}
return 0;
}
I think there are several errors.
count must be initialized, like int count = 0;
count variable is not changed after linearsearch function.
b array should allocated dynamically.
suggested patch is:
#include <stdio.h>
void linearsearch(int n,int a[n],int x,int *count,int **b)
{
count=0;
int i;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
*b = realloc(*b, sizeof(int) * (j + 1));
(*b)[j]=i;
j++;
}
}
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int x;
scanf("%d",&x);
int count = 0;
int *b = NULL;
linearsearch(n,a,x,&count,&b);
for(i=0;i<count;i++)
{
printf("%d",b[i]);
}
return 0;
}
Well the ideal way would be to allocate the memory dynamically based of the number of x found. But well let's look at the errors first. Maybe after this discussion you can write the code.
b[j]=i;
In the called function let's dissect the type of this.
i is of type int. And b[j] is of type int*. Then you assigned them (type mismatched). Then %d expects an int but you passed something of type int*. This is undefined behavior.
Now there was another flaw you had - you passed count and somehow you expect the value you changed in search will be there in main(). C is pass by value and you changed to a local variable. That change is lost when the called function ends.
#include <stdio.h>
#include <stdlib.h>
int* linearsearch(int n,int* a,int x,int* count)
{
*count=0;
if( n <= 0){
fprintf(stderr, "%s\n","Error" );
exit(1);
}
int *t = malloc(sizeof(*t)*n);
if( t == NULL){
perror("Malloc failed");
exit(1);
}
for(int i = 0; i < n; i++)
if(a[i] == x)
t[(*count)++] = i;
int *temp = realloc(t,sizeof(*temp)* (*count));
if( temp == NULL){
perror("Realloc failed");
exit(1);
}
t = temp;
return t;
}
int main(void)
{
int n;
if( scanf("%d",&n)!= 1){
fprintf(stderr, "%s\n", "Error in input");
exit(1);
}
if( n <= 0 ){
fprintf(stderr, "%s\n", "Error in input : must be greater than 0");
exit(1);
}
int a[n];
for(int i=0; i < n; i++)
if(scanf("%d",&a[i])!=1){
fprintf(stderr, "%s\n","Error in input." );
exit(1);
}
int elmt_to_find;
if( scanf("%d",&elmt_to_find)!= 1){
fprintf(stderr, "%s\n", "Error in input : Element to find(must be integer)");
}
int count;
int *b = linearsearch(n,a,elmt_to_find,&count);
for(int i = 0; i < count; i++)
printf("%d ",b[i]);
printf("%s","\n");
free(b);
return 0;
}
If you want to stick with using VLA for b, you can alter your linearsearch to return count only if b is NULL. Then, you can create b as VLA, and pass it back to linearsearch again to be populated.
int count = linearsearch(n, a, x, 0, 0);
int b[count];
linearsearch(n, a, x, count, b);
Then, your function could look like:
int linearsearch(int n,int a[n],int x,int count,int *b[count])
{
int i;
if(count==0)
{
for(i=0;i<n;i++)
{
if(a[i]==x)
{
count+=1;
}
}
}
if (b==0)
{
return count;
}
int j=0;
for(i=0;i<n;i++)
{
if(a[i]==x)
{
b[j]=i;
j++;
}
}
return count;
}

Generating an array of integers

I got a problem in generating an array of integers. the program fills hundreds of cells of the array with numbers like -32429173 instead of 3 cells with numbers from 0 to 3 (for example). Maybe the problem is in the wrong way of allocating memory? Here is the wrong part of the code. Thx for the help in advance.
int* generate()
{
int maxnumb;
int i;
scanf_s("%d",&size); //size of an array
scanf_s("%d",&maxnumb); //asks for maxnumb to fill the array with random numbers from 0 to maxnumb
int* array=(int*)calloc(size,sizeof(int));
for (i=0;i<size;i++)
array[i] = rand() % maxnumb + 1;
return array;
}
Here is the full code
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
int size;
void swap(int* elem1,int* elem2) //swap elements
{
int temp;
temp=*elem1;
*elem1=*elem2;
*elem2=temp;
}
void bublesort(int* array,int size) //bublesort
{
for (int j=1;j<size-1;++j)
{
for (int i=0;i<size-j;++i)
{
if ((array[i])>(array[i+1]))
swap(&array[i],&array[i+1]);
}
}
}
int* enterHand() //handle entering
{
int i;
scanf_s("%d",&size);
int* array=(int*)calloc(size,sizeof(int));
for (i=0;i<size;i++)
{
scanf_s("%d",&array[i]);
}
return array;
}
int* enterFile() //entering from the file
{
int i;
int singlenumb;
FILE* foo;
errno_t err;
err=fopen_s(&foo,"input.txt","r");
if( err == 0 )
{
printf( "The file 'input.txt' was opened\n" );
}
else
{
printf( "The file 'input.txt' was not opened\n" );
}
while (!feof(foo))
{
fscanf_s(foo, "%d", &singlenumb);
size++;
}
size-=1;
int* array=(int*)calloc(size,sizeof(int));
rewind(foo);
i=0;
while (i!=size)
{
fscanf_s(foo, "%d", &array[i]);
i++;
}
fclose(foo);
return array;
}
int* generate()
{
int maxnumb;
int i;
scanf_s("%d",&size); //size of an array
scanf_s("%d",&maxnumb); //asks for maxnumb to fill the array with random numbers from 0 to maxnumb
int* array=(int*)calloc(size,sizeof(int));
for (i=0;i<size;i++)
array[i] = rand() % maxnumb + 1;
return array;
}
void putsFile(int* array, int size)
{
int i=0;
int k;
FILE* fooo;
fopen_s(&fooo,"output.txt","w");
while (i!=size)
{
for (k=0; k<10; k++)
{
fprintf(fooo,"%d ", array[i]);
i++;
}
fprintf(fooo,"\n");
}
fclose(fooo);
}
void printArray(int* array, int size)
{
int i=0;
int k;
while (i!=size)
{
for (k=0; k<10; k++)
{
printf("%d ", array[i]);
i++;
}
printf("\n");
}
}
int main()
{
int choice;
int* pntr;
printf("choose a type of filling an array\n1 = handle filling\n2 = filling from the file\n3 = generating\nenter the number...\n");
scanf("%d", &choice);
switch (choice)
{
case 1: {pntr=enterHand();} break;
case 2: {pntr=enterFile();} break;
case 3: {pntr=generate();} break;
default: {pntr=NULL;}
}
bublesort(pntr,size);
printf("choose a type of typing an array\n1 = console\n2 = file\nenter the number...\n");
scanf("%d", choice);
switch (choice)
{
case 1: {printArray(pntr, size);} break;
case 2: {putsFile(pntr, size);} break;
default: {printf("you entered the wrong number");}
}
return 0;
}
I think you should initialize your maxnumb
First, here is a simpler approach for filling an array.
int randomGenerator(int min, int max);
int main(void)
{
int array[100]//or any size
for(i=0;i<sizeof(array)/sizeof(array[0]);i++)
{
array[i]=randomGenerator(1,3);//will issue only 1, 2 or three (as you requested)
} //change min and max for wider range
return 0;
}
int randomGenerator(int min, int max) //set the range of desired numbers in array
{
int random=0, trying=0;
trying = 1;
while(trying)
{
srand(clock());
random = (rand()/32767.0)*(max+1);
(random >= min) ? (trying = 0) : (trying = 1);
}
return random;
}
There are also some things you can do to make this non-repeating, i.e. so you won't get two Ace of Spades. But for now, you have much bigger issues...
Your code, as is has too many issues to build. If you post a small, buildable section, with the specific problem, it can be better addressed.
The printArray() and putsFile() may print outside array size.
int* enterFile() does not set size to 0 before determining number of int in the file, thus using a potentially unexpected non-zero size.
[Edit] Well size is implicitly set to 0 being in the global uninitialized space. Still, recommend explicitly setting to 0 in enterFile().
#if 0
// The value of size is dependent on program history or uninitialized.
while (!feof(foo)) {
fscanf_s(foo, "%d", &singlenumb);
size++;
}
size-=1;
#else
size = 0; // Reset size to 0
while (1 == fscanf_s(foo, "%d", &singlenumb)) {
size++;
}
#endif
Suggest:
void printArray(int* array, int size) {
// Also in void putsFile(int* array, int size)
int i=0;
while (i < size) {
int k;
for (k=0; k<10; k++) {
printf("%d ", array[i]);
i++;
// Add
if (i >= size) break;
}
printf("\n");
}
}

Generate all possible non-repeating integers from 1 to limit

I'm having a hard time changing up this program. The algorithm is correct already for generating the non-repeating lists. However, I want the list to be generated from a range of the user's integer. (1 to n)
Ex: user inputs 5 -> prints (1 2 3 4 5) then asks for 5 integers to generate the combination(s).
How would I change this so that the combinations are found from (1-n) instead of individually entering the integers n times? Any help would be greatly appreciated.
(Sorry if it's messy, I'm a student :P)
#include<stdio.h> stdio.h
#include<stdlib.h> stdlib.h
int a1[50], a2[50]; // arrays
int count=-1, range;
int w; // user defined variable
void main()
{
printf("Please enter a number. (1-10): ");
scanf("%d", &w);
int x,y; // comparing
printf("You have entered %d\n\n",w);
for(range=1; range<=w; range++){
printf("%d", range);
printf(" ");
} // end for "range"
printf("\n");
for(x=0; x<w; x++){
a1[x]=0;
y=x+1;
scanf("%d\n\n" ,&a2[y]);
}// end for
combo(w);
} // end main
combo(int z) // function with algorithm to find combonations
{
while (w<1 || w>10){
printf("\nThat number is not in range. Please try again. \n\n");
printf("Please enter a number. (1-10): ");
scanf("%d", &w);
} // end while
int x;
a1[z]=++count;
if(count==w){
for(x=0; x<w; x++)
printf("%2d",a2[a1[x]]);
printf(" ");
} // end if
for(x=0; x<w; x++)
if(a1[x]==0)
combo(x);
count--;
a1[z]=0;
} // end "combo"
#include <stdio.h>
#include <string.h>
void swap (int *X, int *Y)
{
int temp;
temp = *X;
*X = *Y;
*Y = temp;
}
void print_array(int *a, int n) {
int i;
printf("\t=> ");
for(i = 0; i < n; i++){
printf("%d, ", a[i]);
}
printf("\n");
}
void mixmatch (int *Arr, int i, int n)
{
int j;
int *A = Arr;
if (i == n)
print_array(A,n+1);
else
{
for (j = i; j <= n; j++)
{
swap((A+i), (A+j));
mixmatch(A, i+1, n);
swap((A+i), (A+j));
}
}
}
int main()
{
int A[10];
int k;
int i;
printf("Enter a number between (1-10):");
scanf("%d", &k);
for(i = 0; i < k && i < 10; i++) {
printf("%d, ",i);
A[i] = i;
}
printf("\n");
mixmatch(A, 0, k-1);
return 0;
}
This is how you can modify it to incorporate integers and arrays of them.

Resources