I'm writing a program to print a numbers in array then used function to split the array to an odd and even number. I've done this part, then I have to sent each of the odd and even array to another function that calculate the largest number in each array and return the calculated value. It seem there something missing in the main function.
#include <stdio.h>
void split();
int largest(int arr[]);
int main() {
int a[11] = {2, 4, 5, 6, 7, 1, 8, 3, 9, 14, 17};
printf("the values of the array is :\n");
for (int i = 0; i < 11; i++) {
printf("%d ", a[i]);
}
split();
int z = largest(odd);
printf("the max value in odd array is :%d\n", z);
}
void split() {
int i, evenNumber = 0, oddNumber = 0;
int even[11], odd[11];
int a[11] = {2, 4, 5, 6, 7, 1, 8, 3, 9, 14, 17};
for (i = 0; i < 11; i++) {
if (a[i] % 2 == 0) {
even[evenNumber++] = a[i];
} else {
odd[oddNumber++] = a[i];
}
}
printf("\nEven :\n");
for (i = 0; i < evenNumber; i++) {
printf("%d ", even[i]);
}
printf("\nOdd :\n");
for (i = 0; i < oddNumber; i++) {
printf("%d ", odd[i]);
}
}
int largest(int odd[]) {
int max;
max = odd[0];
for (int i = 0; i < 11; i++) {
if (max < odd[i]) {
max = odd[i];
}
}
return max;
}
You actually can use arrays in other functions. However, the problem you are running into is scope.
The Problem
In your main function,
int main ()
{
int a[11] = {2,4,5,6,7,1,8,3,9,14,17};
printf("the values of the array is :\n");
for (int i = 0 ; i<11 ; i++){
printf("%d ",a[i]);
}
split();
int z = largest(odd);
printf("the max value in odd array is :%d\n",z);
}
the line int z = largest(odd); uses the variable odd. However, odd is never defined in main. Rather, odd is defined in the scope of split().
It appears you think that because you are calling split() in main, that somehow you will able to access odd in main after you call split(). This is not true. Even though odd is defined in split(), it is defined only in split(). So even though main calls split(), odd is still not defined in main.
This is because a variable is limited to the scope in which it is defined. If a variable is defined in a function (i.e. the function is its scope), it is accessible only within that function, even if that function is used elsewhere. If you want to use a variable outside of the function in which it is defined, you must somehow "return" that variable from the function.
I strongly recommend reading a tutorial on how "scope" works in C, e.g. this tutorial.
The Solution
You have a two main options:
Rewrite split() to somehow return odd.
Move the contents of split() to main. I.e. don't make split() a separate function.
Unless you have a specific reason for keeping split() as a separate function, I would strongly recommend just moving its contents into main. Otherwise, you will have to pass multiple parameters as references to make split() work the way you want it to.
If we move the contents of split() into main (and make the necessary adjustments to remove duplicate variables), this is what the new code will look like:
#include <stdio.h>
int largest(int arr[]);
int main() {
int a[11] = { 2, 4, 5, 6, 7, 1, 8, 3, 9, 14, 17 };
printf("the values of the array is :\n");
for (int i = 0; i < 11; i++) {
printf("%d ", a[i]);
}
int evenNumber = 0, oddNumber = 0;
int even[11], odd[11];
for (int i = 0; i < 11; i++) {
if (a[i] % 2 == 0) {
even[evenNumber++] = a[i];
} else {
odd[oddNumber++] = a[i];
}
}
printf("\nEven :\n");
for (int i = 0; i < evenNumber; i++) {
printf("%d ", even[i]);
}
printf("\nOdd :\n");
for (int i = 0; i < oddNumber; i++) {
printf("%d ", odd[i]);
}
int z = largest(odd);
printf("the max value in odd array is :%d\n", z);
}
int largest(int odd[]) {
int max = odd[0];
for (int i = 0; i < 11; i++) {
if (max < odd[i]) {
max = odd[i];
}
}
return max;
}
One more comment:
Whenever you pass an array to a function, you should always pass the length of the array too. For example:
int largest(int odd[], int len) {
int max = odd[0];
for (int i = 0; i < len; i++) {
if (max < odd[i]) {
max = odd[i];
}
}
return max;
}
And then you would call largest(int[], int) like this:
largest(odd, 11);
Related
I'm currently doing some free exercises on codeStepByStep, and I particularly don't know how to solve the max_row one.
I need to input a 2D array as a function parameter, but it keeps showing me this error:
note: declaration of ‘arr’ as a multidimensional array must have bounds for all dimensions except the first *
It seems like arrays should at least have a predefined column length, but it can't be dynamic like that right?
Here is my code :
int max=row(int numColumn, int arr[][numColumn], int numRow) {
int i, j, sum = 0, maxSum = 0, a, b=0;
for (i=0; i<numRow; i++) {
for (j=0; j<numColumn; j++) {
sum = arr[i][j] + sum;
}
if (maxSum < sum) {
maxSum = sum;
a = i;
}
if (maxSum = sum) {
b = i;
}
if (b < a) {
a = b;
}
}
return a;
}
int main()
{
int list[4][3] = {
{ 3, 8, 12},
{ 2, 9, 17},
{ 43, -8, 46},
{203, 14, 97}
};
printf("%d", max_row(3, list, 4));
return 0;
}
After asking here and there I found that I should start by declaring the column variable, so instead of this :
int max_row(int arr[][numColumn], int numRow, int numColumn)
it should be something like this as in the code above:
int max_row(int numColumn, int arr[][numColumn], int numRow)
but it won't be tested by the website.
The test question:
Write a function named max_row that accepts a number of rows and columns, and a 2-D array of integers, as parameters and that returns the index of the row where the elements add up to the greatest value. For example:
int list[4][3] = {
{ 3, 8, 12},
{ 2, 9, 17},
{ 43, -8, 46},
{203, 14, 97}
};
Then the call of max_row(list, 4, 3) should return 3. If there is a tie between two or more rows, return the row with the smaller index.
Your code should work for an array of any size at least 1x1.
Everything in main is me trying to see if the code works.
It's because you can't declare a multi-dimensional array with a variable as dimension (c and c++ don't support it unless you declare them in the heap memory).
A solution could be this one:
#define MAX 10
int row(int numColumn, int arr[][MAX], int numRow)
{
int i, j, sum = 0, maxSum = 0, a, b = 0;
for (i = 0; i < MAX; i++) {
for (j = 0; j < MAX; j++) {
sum = arr[i][j] + sum;
}
if (maxSum < sum) {
maxSum = sum;
a = i;
}
if (maxSum == sum) {
b = i;
}
if (b < a) {
a = b;
}
}
return a;
}
In the first line you declare a constant named MAX with value 10, then you use it to initialize the array.
Also I don't understand the use of maxSum and b, since you never actually use maxSum (you just initialized it) and you don't return b.
Plus you didn't even initialize a (you can't return a not initialized variable).
Moreover REMEMBER that you have to write == to make a comparison in an if statement, not =.
For my studies, I have to write a C function GetEvenNumber:
parameters: array with n integers + array size;
returns tr array which contains even integers from td.
I don't know a priori the length of the array tr.
My below code returns errors:
#include <stdio.h> // define the header file
int *GetEvenNumber(int t[], int size)
{
int tr[];
int j = 0;
for (int i = 0; i < size; i++)
{
if (t[i] % 2 == 0)
{
printf("%d is even \n", t[i]);
tr[j] = t[i];
j++;
}
}
return tr;
}
int main() // define the main function
{
int *t; // = {4, 3, 1, 8, 6 };
int *tr = GetEvenNumber(t, 5);
for (int i = 0; i < 5; i++)
printf("%d \n", tr[i]);
}
I get error:
error: array size missing in 'tr'
int tr[];
warning: function returns address of local variable [-Wreturn-local-addr]
return tr;
How do I fix that? Thanks.
You mentioned that you could not use malloc() to dynamically create tr within GetEvenNumber() to address the two issues raised by your copmiler. This leaves making tr a global variable, or as here pass in the result array tr to be filled out:
#include <stdio.h>
#include <stdlib.h>
void GetEvenNumber(size_t size, const int *td, size_t *size2, int *tr) {
*size2 = 0;
for(size_t i=0; i<size; i++)
if(td[i] % 2 == 0)
tr[(*size2)++] = td[i];
}
int main() {
int td[] = {4, 3, 1, 8, 6 };
size_t size = sizeof(td) / sizeof(*td);
int tr[size];
size_t size2;
GetEvenNumber(size, td, &size2, tr);
for (size_t i=0; i < size2; i++)
printf("%d \n", tr[i]);
}
If the input array td contains uneven elements, then the result array tr have fewer valid elements than the input. I used size2 here to tell caller how many elements are valid in tr. Your code did not assign any values to, in this example, last 3 elements. You don't tell us what should happen with those last elements.
In modern C, if you specify the size before the array in the argument, then you can use the size in array specification which help document what is going on.
The error is due to
int tr[];
because you have to specify the size of your array during its creation.
I suggest trying to add a function that returns the number of even numbers in the array:
int getEvenNum(int t[], int lent){
int numEven = 0; // initialize counter to zero
for(int i = 0; i < lent; i++){ // for each element of the array
if ((t[i] % 2) == 0){ // if it's even,
numEven++; // add 1 to counter
}
}
return(numEven); // finaly returns the value of the counter
}
and then you replace the int tr[]; by int tr[getEvenNum(t, size)]; (maybe there's a ; after the getEvenNum(t, size) but I'm not sure)
Since the array tr can have AT MOST the same number of elements as the original integer array, it would be safe to declare the array with the same size as the array 't[]'.
I have made some changes to your code. Try the following:
#include<stdio.h> // define the header file
void GetEvenNumber(int *t, int* tr, int size, int *pCountEven)
{
int i, j=0;
for (i=0; i < size; i++)
{
if(t[i]%2==0)
{
printf("%d is even \n", t[i]);
tr[j++] = t[i];
}
}
*pCountEven = j;
}
int main() // define the main function
{
int t[] = {4, 3, 1, 8, 6 };
int tr[5], countEven = 0, i;
GetEvenNumber(t, tr, 5, &countEven);
for (i=0; i < countEven; i++)
printf("%d\n", tr[i]);
return 0;
}
Edit: As #chqrlie (who is an experienced coder) pointed out, we can simply return the length of the array instead of taking the address of a variable.
So alternatively, you can try this:
#include <stdio.h> // define the header file
int GetEvenNumber(int *t, int *tr, int size) {
int i, j = 0;
for (i = 0; i < size; i++) {
if (t[i] % 2 == 0) {
printf("%d is even \n", t[i]);
tr[j++] = t[i];
}
}
return j;
}
int main() // define the main function
{
int t[] = { 4, 3, 1, 8, 6 };
int tr[5], countEven = 0, i;
countEven = GetEvenNumber(t, tr, 5);
for (i = 0; i < countEven; i++)
printf("%d\n", tr[i]);
return 0;
}
The task is as follows: to fill the file with numbers using the generation() function - an array cannot be used here. Then read the digits into the array by the read_file() function into the array and sort it using the quick sort method. Output to the console.
I wrote the code as I logically understood it myself, but a set of values is output to the console after sorting, as it is output in case of an error with a lack of memory, random numbers with cons sometimes. Maybe it's worth filling in a dynamic array? And why, if I know a specific number of elements?
Please help me figure it out.
#include <stdio.h>
#include <stdlib.h>
#define N 10
#define A -25000
#define B 25000
void generation();
void read_file();
void method_simple_sort();
int main(void) {
generation();
method_simple_sort();
return EXIT_SUCCESS;
}
void generation() {
FILE *file;
int i;
file = fopen("index.txt", "w");
srand(time(0));
for (int i = 0; i < N; i++) {
fprintf(file, "%d\n", A + rand() % (A - B + 1));
}
fclose(file);
}
void read_file() {
FILE *file;
int i, a[N] = { 0 };
file = fopen("index.txt", "r");
for (i = 0; i < N; i++) {
fscanf(file, "%d ", &a[i]);
}
fclose(file);
for (int i = 0; i < N; i++)
printf("%d ", a[i]);
}
void method_simple_sort() {
int a[N], i = 0, k = 0, ind_max = 0, temp = 0;
read_file();
for (k = 0; k < N - 1; k++) {
ind_max = k;
for (i = 1 + k; i < N; i++) {
if (a[i] > a[ind_max]) {
ind_max = i;
}
}
temp = a[k];
a[k] = a[ind_max];
a[ind_max] = temp;
}
// вывод результатов в файл
printf("\n\nПростого выбора: ");
for (int i = 0; i < N; i++) {
printf("%d ", a[i]);
}
printf("\n\n\n\n");
}
The function method_simple_sort defines a local array variable int a[N].
It then calls read_file(), but read_file() does not fill this local array variable defined in method_simple_sort.
Instead it fill its own local array variable (called also int a[N], but it's a different one than the one in method_simple_sort).
The bottom line is that when method_simple_sort attempts to sort a it sorts an array containing uninitialized data.
Hence the "garbaged" values that you see printed at the end.
The array used by the methods read_file and method_simple_sort aren't the same. When you declare anything inside a function it is translated at low level in space to allocate on the stack when you call the function.
You should transform read_file(void) into read_file(int *a) without declaring another instance of an array inside read_file.
By doing that you can pass a reference to the array declared inside method_simple_sort.
In particular:
void read_file(int *a) {
FILE *file;
int i;
/* a[N] = { 0 };*/
...
}
void method_simple_sort() {
int a[N], i = 0, k = 0, ind_max = 0, temp = 0;
read_file(a);
...
}
Context
I created this simple code where I store various arrays in my_arrays() function and different functions (in my example the main()) can get the hard-coded arrays via the function my_arrays().
See the code here:
#include <stdio.h>
int my_arrays(int *size, int **arrays) {
size[0] = 3;
int array_1[3] = {1, 2, 3};
arrays[0] = array_1;
size[1] = 5;
int array_2[5] = {2, 3, -5, 7, 11};
arrays[1] = array_2;
}
int main() {
int num_of_arrays = 2;
int sizes[2];
int *arrays[2];
my_arrays(sizes, arrays);
for (int i=0; i < num_of_arrays; i++) {
int *array = arrays[i]; // point to sub-array
int size = sizes[i];
printf("array[%d]: {", i);
for (int x=0; x < size; x++) {
printf(" %d", array[x]);
}
printf(" }\n", i);
}
return 0;
}
In the main() I then loop through the sub-arrays and loop through each individual number and print it out.
What I expect the code above to print out is:
array[0]: { 1 2 3 }
array[1]: { 2 3 -5 7 11 }
But when compiling and running I get this:
array[0]: { 1993067712 1617605192 -2 }
array[1]: { 3936256 8 6422188 7 6422476 }
Why?
In my_arrays, array_1 and array_2 are local arrays on the stack. They will be invalid as soon as you return from my_array. Now arrays[0] and arrays[1] hold pointers to invalid or "stale" memory. Accessing that is undefined behaviour.
(The garbage values you see shows you that your arrays have been overwritten by other uses of the stack space, probably by calls to printf.)
If you want to create arrays, you can allocate memory on the heap:
int my_arrays(int *size, int **arrays)
{
size[0] = 3;
arrays[0] = malloc(3 * sizeof(int));
arrays[0][0] = 1;
arrays[0][1] = 2;
arrays[0][2] = 3;
// ... initialize other arrays ...
return 0;
}
You should explicitly free it after you're done using it:
// at the end of main
for (int i=0; i < num_of_arrays; i++) {
free(arrays[i]);
}
int array[10] = {1,2,3,4,5}
from my understanding, the rest of the indexes that haven't been assign a value will be 0. If I want to move every element to the left (I am wanting to remove the first value i.e. index 0). How do I do this without causing duplicate values for the last index with a integer assigned?
For example:
current array
output: 1234500000
+1 to the left:
output: 2345500000
I tried the following code:
void order_array(int size, int array[])
{
for (int i = 0; i < size-1; i++)
{
if (array[i] == 0)
{
array[i-1] = 0;
}
array[i] = array[i+1];
}
}
expected output after method execution:
output: 2345000000
Also before someone says this is a duplicate, I have looked around and no thread explains with fixed arrays, i.e. with 0's as default values.
Appreciate your response.
if (array[i] == 0)
{
array[i-1] = 0;
}
I don't understand why this block is there. It's not possible to get inside the if statement.
With your expected output and given this is an array of ints, I suspect the solution is to only output four values in your print statement, but if the last element of the array should be zero, you can just do this after your for loop:
array[size-1] = 0;
If you don't want rotation then:
int arr[]; //initialize it
int siz=sizeof(arr)/sizeof(arr[0]);
int index=0;
while(index<siz-1)
{
arr[index]=arr[index+1];
index++;
}
arr[index]=0; //0 default value at the end of the array
This will work fine
You just need to manually set the last value to zero at the end. I'd also consider using the built-in memmove function which is designed for moving around data where the source and destination overlap.
void order_array(int size, int array[]){
memmove(array, array+1, (size-1) * sizeof(array[0]));
array[size-1] = 0;
}
#include <stdio.h>
#define ARRAY_SIZE 10
void order_array(int size, int* array) {
for (int i = 0; i < size; i++) {
if (!array[i]) {
continue;
}
if (i + 1 < size)
array[i] = array[i + 1];
}
}
int main() {
int array[ARRAY_SIZE] = {1, 2, 3, 4, 5};
printf("intput: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
order_array(ARRAY_SIZE, array);
printf("output: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
return 0;
}
Maybe you should consider the last value that not equal to default value 0.
Execute in shell:
gcc -o a.out a.c && ./a.out
intput: 1234500000
output: 2345000000