Here's a fairly simple program that finds the max element of an 2d array grades and prints it out to the screen
#include <stdio.h>
const int t = 5;
int num_of_students;
int better(int grades[num_of_students][t], int num_of_students)
{
int i, k;
int max = grades[0][0];
for (i = 0; i < num_of_students; i++)
{
for (k = 0; k < t; k ++)
{
if (grades[i][k] > max)
{
max = grades[i][k];
}
}
}
return max;
}
int main(void)
{
int i, k;
printf("Give the number of students who took the test: ");
scanf("%i", &num_of_students);
int grades[num_of_students][t];
for (i = 0; i < num_of_students; i++)
{
printf("Student %i\n", i+1);
for (k = 0; k < t; k++)
{
printf("Give the score on test %i: ", k+1);
scanf("%i", &grades[i][k]);
while (grades[i][k] < 0 || grades[i][k] > 100)
{
printf("Not an acceptable score, try again %i: ", k+1);
scanf("%i", &grades[i][k]);
}
}
}
int max = better(grades[num_of_students][t], num_of_students);
printf("The best score is %i\n", max);
}
Yet when I'm trying to run the program the following errors pop up:
test.c:47:45: warning: passing argument 1 of 'better' makes pointer from integer without a cast [-Wint-conversion]
test.c:6:16: note: expected 'int (*)[(sizetype)t]' but argument is of type 'int'
For starters change the function declaration from
int better(int grades[num_of_students][t], int num_of_students)
to
int better(int num_of_students, int grades[num_of_students][t] )
Otherwise it is unclear whether in the declaration of the first parameter int grades[num_of_students][t] there is used the global variable num_of_students or the identifier of the second parameter. That is the function declaration as is will confuse readers of the code.
And call it like
int max = better( num_of_students, grades );
Otherwise you are trying to pass the non-existent element of the array grades[num_of_students][t] of the type int instead of the array itself.
Related
I need help. It doesnt display the printf in the mean function. I am doing a dynamic allocation in c and the add function works but the mean function does not display. There is no problem to the add function it works but the max does not. I am sorry I know this problem is simple but still cant get the answer. I am also getting a warning to the add function during the call in main.
This is my code:
typedef int* Statistician;
void add(Statistician answer, int *count, int *SIZE, int item);
|
[Note] expected 'Statistician' {aka 'int *'} but argument is of type 'int **'
int main() {
int SIZE;
Statistician *answer;
int count;
int item;
add(answer, count, SIZE, item);
|
//[Warning] passing argument 1 of 'add' from incompatible pointer type [-Wincompatible-pointer-types]
printf("\nThe mean is: %.2f", mean(answer, SIZE));
return 0;
}
This is the add function:
void add(Statistician answer, int *count, int *SIZE, int item) {
int i;
printf("Enter n: ");
scanf("%d", &item);
answer = (int*)malloc(item * sizeof(int));
if(item == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {
for(i = 0; i < item; ++i) {
scanf("%d", &answer[i]);
}
printf("Elements of array are: ");
for(i = 0; i < item; i++) {
printf("%d ", answer[i]);
}
if(item == 10) {
int m;
printf("\nAppend array: ");
scanf("%d", &m);
answer = realloc(answer, m * sizeof(int));
for(i = item; i < item + m; i++) {
scanf("%d", &answer[i]);
}
item = item + m;
int temp, j;
for(i = 0; i < item; i++) {
for(j = 0; j <= i; j++) {
if(*(answer + i) < *(answer + j)) {
temp = *(answer + i);
*(answer + i) = *(answer + j);
*(answer + j) = temp;
}
}
}
printf("Final array: \n");
for(i = 0; i < item; ++i) {
printf("%d ", answer[i]);
}
}
}
}
This is the max function that doesnt display:
float mean(Statistician answer, int count) {
int mean =0;
int cnt = 0;
for(int i=0;i<count;i++){
mean = mean + answer[i];
cnt++;
}
mean = mean / cnt;
return mean;
}
I fully expected to find a duplicate but I didn't.
The first argument to add is declared to be int ** (via typedef) and you passed it a paramter of type int *. The compiler will let you do this with a warning, but it's almost always wrong. Don't do it.
If you're running 64 bit code, anything can happen after you stomp memory. 32 bit code is slightly more predictable but it's still going to end badly.
From your code, it looks like you want void add(Statistician *answer, Statistician answer; and add(&answer.
The deep learning of pointers is here. The thing you need to modify in the calling function is the thing whose address is passed to the called function. Allocating arrays with malloc almost always ends up being double pointers.
When running this program using pointers and arrays to calculate the grade point average from the user input, it outputs a garbage value. How can I alter the code so that the output is correct?
void Insert_Grades(int *array)
{
int grades[4];
int i;
for (int i = 0; i < 4; i++)
{
printf("Enter grade %d: ", i + 1);
scanf("%d", &grades[i]);
}
array = grades;
}
void Calculate_Avg(int *array)
{
int i;
float avg;
float sum = 0;
for (i = 0; i < 4; i++)
{
sum += *(array + i);
}
avg = sum / 4;
printf( "Grade point average is: %f ", avg);
}
int main()
{
int grades[4];
int i;
printf("Enter the number of grades:\n");
Insert_Grades(grades);
Calculate_Avg(grades);
printf("\n");
return 0;
}
you cant assign arrays.
This operation assigns local pointer array with reference of the local array grades. For the extral world this operation means nothing.
array = grades;
You need to copy values instead.
memcpy(array, grades, sizeof(grades));
or
for (size_t index = 0; index < 4; index++)
array[index] = grades[index];
There are multiple problem in your code:
in function Insert_Grades, value are read into the local array grades. The last instruction array = grades has no effect because it only modifies the argument value, which is just local variable, a pointer to int that now points to the first element of grade array.
This explains why the program outputs garbage because the array grades defined in the main() function is uninitialized and is not modified by Insert_Grades().
You could copy the array grade to the caller array pointed to by array, but it seems much simpler to use the array pointer to read the values directly where they belong.
the variable i is defined multiple times, with nested scopes.
you should test the return value of scanf() to detect invalid or missing input.
Here is a modified version:
#include <stdio.h>
void Insert_Grades(int *array, int count) {
for (int i = 0; i < count; i++) {
printf("Enter grade %d: ", i + 1);
if (scanf("%d", &array[i]) != 1) {
fprintf(stderr, "invalid input\n");
exit(1);
}
}
}
float Calculate_Avg(const int *array, int count) {
float sum = 0;
for (int i = 0; i < count; i++) {
sum += array[i];
}
return sum / count;
}
int main() {
int grades[4];
int count = sizeof(grades) / sizeof(*grades);
float avg;
printf("Enter the grades:\n");
Insert_Grades(grades, count);
avg = Calculate_Avg(grades, count);
printf("Grade point average is: %.3f\n", avg);
return 0;
}
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);
}
I have a function that takes array 1 and copies/manipulates it to array 2. Basically what it does is take the user input in array one, lets say (2, 3, 3) and array 2 is stored as (2, 0, 3, 0, 3). I know this works because it worked without implementing a function but sadly I have to have one. I cannot for the life of me figure out how to call the function, I believe I don't need a return since its a void and not returning a value. Below is my code any help would be appreciated.
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
int a1[n];
int a2[2*n];
printf("Enter the length of the array: ");
scanf("%d",&n);
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&a1[i]);
}
insert0(); //call function which is wrong and I cannot get anything to work
for( i = 0; i < n*2; i++){ //prints array 2
printf("%d", a2[i]);
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
a2[i+i+1] = 0;
}
}
}
Modifying n after declaraing a1 and a2 won't magically increase their size. Declare a1 and a2 after reading the size into n to use variable-length arrays.
You must pass proper arguments to call insert0.
Defining functions inside functions is GCC extension and you shouldn't do that unless it is required.
a2 should have n*2 - 1 elements, not n*2 elements.
After moving it out of main(), i is not declared in insert0, so you have to declare it.
You should check if readings are successful.
Corrected code:
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
printf("Enter the length of the array: ");
if(scanf("%d", &n) != 1){
puts("read error for n");
return 1;
}
if(n <= 0){
puts("invalid input");
return 1;
}
int a1[n];
int a2[2*n-1];
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
if(scanf("%d", &a1[i]) != 1){
printf("read error for a1[%d]\n", i);
return 1;
}
}
insert0(n, a1, a2);
for( i = 0; i < n*2-1; i++){ //prints array 2
printf("%d", a2[i]);
}
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
int i;
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
if (i+1 < n){ // don't put 0 after the last element
a2[i+i+1] = 0;
}
}
}
So I am currently getting into programming and I'm trying to write this code, but I am having trouble with arrays. I have read a lot of articles online and it seems that this code should work, but for some reason there is an error when I pass my arrays between my functions. Ignore the commented out section in the middle that is where I got it to work inside my main function. For this assignment I need it to work in the functions I defined below. I am just wanting to initialize my array in one function then print it out in the other.
Thanks!
here is the error it displays
prelab7.c:32: warning: passing argument 1 of ‘print_array’ makes pointer from integer without a cast
prelab7.c:7: note: expected ‘int *’ but argument is of type ‘int’
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int errorcheck(int );
void intializearrary(int[], int);
void print_array(int [], int);
int main()
{
int maxsize,i;
int n[maxsize];
printf("\nEnter the size of the input: ");
scanf("%d", &maxsize);
while (errorcheck (maxsize))
{
printf("\nInvalid input enter the size of the input again");
scanf("%d", &maxsize);
}
/* srand(time(NULL));
for (i = 0; i < maxsize; i++)
{
n[i] = generaterandomnumber();
printf("\nn[%d]=%d", i, n[i]);
}
*/
print_array( n[i], maxsize);
return 0;
}
int errorcheck (int maxsize)
{
if (maxsize < 0 || maxsize > 100)
return 1;
else
return 0;
}
void initializearrary( int n[],int maxsize )
{
int i;
srand(time(NULL));
for (i = 0; i < maxsize; i++)
{
n[i] = rand()%10;
}
}
void print_array(int n[], int maxsize)
{
int i; //counter
printf("\nInput Array\n");
for (i = 0; i < maxsize; i++)
{
{
printf("\t%d", n[i]);
}
}
/*int generaterandomnumber()
{
return rand()%10;
}*/
Move
int n[maxsize];
Just after the while loop and change
print_array( n[i], maxsize);
To
print_array( n, maxsize);
The former is done so that maxsize gets initialized before the VLA is constructed.
The latter is done because print_array expects an int* as the first argument, but you pass an invalid argument n[i] which is of type int.