Using array of struct in a function? - c

I'm trying to write a function that changes one value of the elements in an array of struct, but it isn't working, the function does nothing. What am I doing wrong?
Input:
300
9
1999
1050
301
5
2000
1200
20
Expected output:
300 1260
Actual output: nothing
#include <stdio.h>
typedef struct
{int codice;
int mese;
int anno;
int stipendio;}
dipendente;
void aumento (dipendente a[], int dim, int n){
int i;
for (i=0; i<dim; i++)
{if (a[i].anno<2000) a[i].stipendio=a[i].stipendio+(a[i].stipendio*n)/100;;
if (a[i].anno==2000)
{if (a[i].mese<5)
a[i].stipendio=a[i].stipendio+(a[i].stipendio*n)/100;}}
}
int main () {
int i;
int p;
dipendente a[2];
for (i=0; i<2; i++){
scanf("%d",&a[i].codice);
scanf("%d",&a[i].mese);
scanf("%d",&a[i].anno);
scanf("%d",&a[i].stipendio);
}
scanf("%d", &p);
aumento (a, 2, p);
for (i=0; i<2; i++)
{if(a[i].stipendio>1200)
printf("%d %d", a[i].codice, a[i].stipendio);}
return 0; }

There two problems.
As #n.m. pointed out in comments: if (a[i].anno=2000) is doing an assignment and is always true (because 2000 is true). You want to compare. Use double == for it if (a[i].anno == 2000)
As #SamiHult pointed out in comments: n/100 will always be 0 for any 0 <= n && n < 100, because n is an int. Use double or float to have floating point math. Or as #alk pointed out, you can first multiply then divide, so that you can stay in integer math (a[i].stipendio * n) / 100
This is good code, but indentation just hurts.
After fixing those errors:
#include <stdio.h>
typedef struct {
int codice;
int mese;
int anno;
int stipendio;
} dipendente;
void aumento(dipendente a[], int dim, int n) {
int i;
for (i = 0; i < dim; i++) {
if (a[i].anno < 2000) {
a[i].stipendio = a[i].stipendio + a[i].stipendio * ((double)n / 100);
}
if (a[i].anno == 2000) {
if (a[i].mese < 5) {
a[i].stipendio = a[i].stipendio + a[i].stipendio * ((double)n / 100);
}
}
}
}
int main() {
int i;
int p;
dipendente a[2];
for (i = 0; i < 2; i++){
scanf("%d", &a[i].codice);
scanf("%d", &a[i].mese);
scanf("%d", &a[i].anno);
scanf("%d", &a[i].stipendio);
}
scanf("%d", &p);
aumento(a, 2, p);
for (i = 0; i < 2; i++) {
if (a[i].stipendio > 1200) {
printf("%d %d", a[i].codice, a[i].stipendio);
}
}
return 0;
}
your code prints the expected output.

Related

Why do i get segmentation fault 11?

Why do I get segmentation fault 11? I get it quite often, and I know this time it is about the function. If anyone can help, please do, the code is down below! I am trying to make a program, that WITH A FUNCTION, can rearrange an array in ascending order and then print it in main in reverse order.
#include "stdio.h"
void changxr(int *counter, int *arrsize, int *j, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(&counter, &arrsize, &j, &arr[&counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int *counter, int *arrsize, int *j, int *arr[])
{
int a;
for (*counter = 0; *counter < *arrsize; *counter++)
{
for (*j = *counter + 1; *j < *arrsize; *j++)
{
if (*arr[*counter] > *arr[*j])
{
a = *arr[*counter];
*arr[*counter] = *arr[*j];
*arr[*j] = a;
}
}
}
}
New code:
#include "stdio.h"
void changxr(int arrsize, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(arrsize, &arr[counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int arrsize, int *arr[])
{
int a, counter, j;
for (counter = 0; counter < arrsize; counter++)
{
for (j = counter + 1; j < arrsize; j++)
{
if (*arr[counter] > *arr[j])
{
a = *arr[counter];
*arr[counter] = *arr[j];
*arr[j] = a;
}
}
}
}
This is what I got from debugging:
"Program received signal SIGSEGV, Segmentation fault.
0x0000555555555355 in changxr (arrsize=3, arr=0x0) at main.c:33
33 for(j=counter+1; j<arrsize; j++) { if(*arr[counter]>*arr[j]){
(gdb) continue"
You do not need two levels of indirection (int *arr[], *arr[counter], *arr[j]). When arr is passed to a function, it will decay to a pointer-to-its-first-element, or more simply, an int *.
&arr[counter] is also an int *, but it is the address of the array element one past the elements you've initialized. This would start your sorting function in the incorrect place.
Your program segfaults because it attempts to use this value as an int ** (int *[]).
gcc -Wall highlights this clearly:
prog.c: In function ‘main’:
prog.c:24:22: warning: passing argument 2 of ‘changxr’ from incompatible pointer type [-Wincompatible-pointer-types]
24 | changxr(arrsize, &arr[counter]);
| ^~~~~~~~~~~~~
| |
| int *
prog.c:3:32: note: expected ‘int **’ but argument is of type ‘int *’
3 | void changxr(int arrsize, int *arr[]);
| ~~~~~^~~~~
Things to do:
Simply pass the array and the length of the array to your function.
Use a single level of indirection in your function definition, and when accessing the array.
Use a variable-length array.
Use an auxiliary function for printing.
Declare variables when you need them, in the correct scope.
You should also consider checking the return value of scanf is the expected number of successful conversions.
The refactored code:
#include <stdio.h>
void changxr(int *a, size_t length)
{
for (size_t i = 0; i < length; i++) {
for (size_t j = i + 1; j < length; j++) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void print_reverse(int *a, size_t length)
{
printf("[ ");
while (length--)
printf("%d ", a[length]);
printf("]\n");
}
int main(void)
{
size_t size;
printf("Pick an array length: ");
if (1 != scanf("%zu", &size) || size == 0) {
fprintf(stderr, "Invalid length input.\n");
return 1;
}
int array[size];
printf("Enter %zu numbers:\n", size);
for (size_t i = 0; i < size; i++) {
if (1 != scanf("%d", array + i)) {
fprintf(stderr, "Invalid integer input.\n");
return 1;
}
}
printf("Array (in reverse): ");
print_reverse(array, size);
changxr(array, size);
printf("Array, Sorted (in reverse): ");
print_reverse(array, size);
}

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

Unable to get result for dot product C programing

If I print result inside my function, I get the correct answer but if I print the result in main, I get 1. What am I doing wrong?
#include <stdio.h>
int dotpro(int v1[], int v2[], int result, int n);
int main(void) {
int i, n;
printf("Enter n: ");
scanf("%d", &n);
int v1[n], v2[n], result;
printf("Enter arr1: ");
for(i= 0; i < n; i++)
scanf("%d", &v1[i]);
printf("Enter arr2: ");
for(i= 0; i < n; i++)
scanf("%d", &v2[i]);
dotpro(v1, v2, result, n);
// enter code here
}
int dotpro(int v1[], int v2[], int result, int n) {
int i;
for (i = 0; i < n; i++) {
result += (v1[i] * v2[i]);
}
printf("%d", result);
}
You are forgetting to return the result and are attempting to pass the result parameter by value instead of by pointer reference.
Instead of this:
int dotpro(int v1[], int v2[], int result, int n) {
int i;
for (i = 0; i < n; i++) {
result += (v1[i] * v2[i]);
}
printf("%d", result);
}
Do this:
int dotpro(int v1[], int v2[], int n) {
int i;
int result = 0;
for (i = 0; i < n; i++) {
result += (v1[i] * v2[i]);
}
return result;
}
And adjust the declaration at the top of the file to match:
int dotpro(int v1[], int v2[], int n);
Then in main, invoke as follows:
result = dotpro(v1, v2, n);
printf("result = %d\n", result);

Create a dynamic array and assign random integer values to it?

int* create_array(char category, int n){
int *a;
a = malloc(n* sizeof(int));
for (int i = 0; i < n; i++) {
int x;
srand( time(NULL));
x = rand();
a[i] = x;
}
When I print this code, it just prints the same random variable 'n' times.
You can use srand(getpid() or you can specify ther range of random numbers using x=rand()%11 generates from 0-10;
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int *create_array(char category, int n);
int
main(int argc, char const *argv[]) {
time_t t;
int *array;
int i, n;
char category;
srand((unsigned)time(&t));
printf("Enter category: ");
if (scanf("%c", &category) != 1) {
printf("Invalid category.\n");
exit(EXIT_FAILURE);
}
printf("Enter n numbers: ");
if (scanf("%d", &n) != 1) {
printf("Invalid n value.\n");
exit(EXIT_FAILURE);
}
array = create_array(category, n);
printf("Your n random numbers between 0-10:\n");
for (i = 0; i < n; i++) {
printf("%d ", array[i]);
}
free(array);
return 0;
}
int
*create_array(char category, int n) {
int *array;
int i, candidate;
array = malloc(n * sizeof(*array));
for (i = 0; i < n; i++) {
candidate = rand() % 10;
array[i] = candidate;
}
return array;
}

Why does this program crashes on execution?

I am trying to run this code on Dev C++ but it keeps on crashing after the user inputs the two numbers. The program takes input m and n from user two numbers and then returns the output as the solution of the function A which is:
A(m,n) = A(m,n-1)+ A(m-1, n) , if m,n >0
A(m,n) = m-n if m or n <0
Can anybody please tell me why is it happening?
#include<stdio.h>
#include<stdlib.h>
int main() {
int num1=0;
int num2=0;
int rows=0;
int columns=0;
int i,j,**array;
printf("Enter two non-negative integer numbers \n");
scanf("%d %d",&num1,&num2);
//create 2d-Array
rows=num1+1;
columns=num2+1;
array=malloc(rows * sizeof(int *));
for(i=0;i<rows;i++)
{
array[i]=malloc(columns*sizeof(int));
}
//Fill data in array
computeArray(array,rows,columns);
// Display contents of array
for (i = 0; i < rows; i++ )
{
for(j= 0; j < columns; j++ )
{
printf("array[%d][%d] = %d\n", i,j, array[i][j] );
}
}
getch();
return 0;
}
int computeArray (int **array, int rows, int columns) {
int i,j;
for(i=0; i<rows;i++)
{
for(j=0;j<columns;j++)
{
array[i][j]=computeFunction(array,i,j);
}
}
return **array;
}
int computeFunction(int **array, int i, int j) {
int value=0;
if((i<0)||(j <0))
{
value = i-j;
printf("%d",value);
return value;
}
else
{
value = (array[i][j-1] + array[i-1][j]);
printf("%d",value);
return value;
}
return value;
}
When program's behavior is undefined, anything could happen. You should declare a prototype for the function computeArray and computeFunction before main:
int computeArray (int **array, int rows, int columns);
int computeFunction(int **array, int i, int j);
and change
if((i<0)||(j <0)) {...}
in computeFunction to
if((i<=0) || (j <= 0)){...}
&& instead of || may help.
The code fails at the
value = (array[i][j-1] + array[i-1][j]);
line, when j==0.
Debuggers tend to be very useful for spotting simple mistakes. Use them.

Resources