Integer array passed as a Structure variable [duplicate] - c

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 8 years ago.
Here is my code, cant figure out why the size of array is 2.
Help me out in correcting my code, so that i can get the Max() function right.
//Max() gets the max value and Min()gets min value
#include <stdio.h>
#include "conio.h"
struct test {
int input[10];//input array , I need to get out Max and min functions right
int min;
int max;
} testDB[2] =
{
{{1,2,3,4,5,6},1,6},
{{3,4,5},3,5},
};
int Max(int* input){
int max,i,size;
max = input[0];
size = sizeof(input)/sizeof(input[0]);
printf("\n-----------\n");//print debugging
printf("\t%d",size);
printf("\n-----------\n");//print debugging
for(i=0;i<size;i++)
{
if(max<input[i])
max = input[i];
printf("%d\n",max);
}
return max;
}
int Min(int*input)
{
int min,i;
min = input[0];
for(i=0;i<sizeof(input)/sizeof(input[0]);i++)
{
if(min>input[i])
min = input[i];
}
return min;
}
void testCases()
{
int max,min,i;
for(i=0; i<2; i++) {
printf("Test cases for Max\n");
max = Max(testDB[i].input);
if((testDB[i].max==max)) printf("PASSED\n"); else printf("FAILED\n");
printf("TestCases for Min\n");
min = Min(testDB[i].input);
if((testDB[i].min==min)) printf("PASSED\n"); else printf("FAILED\n");
}
}
int main()
{
testCases();
return 0;
}
This is probably it , But as a newbie I am not able to figure this thing

The reason for size of array is 2 is
look at the
} testDB[2] =
{
{{1,2,3,4,5,6},1,6},
{{3,4,5},3,5},
};
in this case, either it goes with one value from ([1,2,3,4,5,6],1,6) or it goes with the ([3,4,5],3,5).
So as it store only 2 digit the size of array is 2. as simple as that.
Megan 35 : n2KVjLKVmLKukLK7muG+lgK0lHzZlwu5

Related

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

C Pointer to an Array example stops working

I'm working on an example and my code is stopped woking when I run it.(Note that I translated the question to English so sorry for grammar mistakes.)
Here is the question:
myShrink() function's prototype is like this:
void myShrink(int *param1, const int param2);
myShrink() function should find the average of the array param1 then should increment the element by 1 if its less than average, or should decrement the element by 1 if it's more than average. param2 is a number of elements in an array.
Here is the content of the main() function:
void myStretch(int *param1, const int param2);
int main () { int myArray[] = {2, 4, 2, 4, 2, 4};
int index;
myStretch(myArray, 6);
printf("UPDATED ARRAY: ");
for(index = 0; index < 6; index++){
printf("%d\t", myArray[index]);
}
return 0;
}
---------The result when we run the program:-----
UPDATED ARRAY: 1 5 1 5 1 5
Now this was the question part what we need to is basically programming the content of myShrink() function and here is my work:
void myShrink(int *param1, const int param2)
{
int array[param2];
param1=array;//Using pointer to point elements of array
int average=0;
int i,j;
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
*(param1+j)+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
*(param1+j)-=1;//decrement
}
}
}
But its stops working when I run it. Where I did make mistake and how can I fix it?
Just do this:
#include<stdio.h>
void myStretch(int *param1, const int param2);
int main () { int myArray[] = {2, 4, 2, 4, 2, 4};
int index;
myStretch(myArray, 6);
printf("UPDATED ARRAY: ");
for(index = 0; index < 6; index++){
printf("\n%d\t", myArray[index]);
}
return 0;
}
void myStretch(int *param1, const int param2)
{
int average=0;
int i,j;
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
(*(param1+j))+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
printf("%d ",(*(param1+j)));
(*(param1+j))-=1;//decrement
}
}
}
Now first thing: your result is wrong. It should be 3 3 3 3 3 3. As the average in this case is 3 and therefore 2 will become 3 and 4 will also become 3. Secondly you don't have to assign a new array inside the function. Just do it this way. Third mistake:
*(param1+j)>average
should be replaced by
(*(param1+j))>average
and similarly for less than sign.
UPDATE: Also note that many people argue that array[param2] is legal or not. When you declare such an array they are called Variable Length Array(VLA). This is allowed in modern C compilers but older compilers like Turbo C don't allow.
In below myShrink function, after 'param1=array;' statement param1 start pointing to array which has garbage inside.
void myShrink(int *param1, const int param2){
int array[param2];
param1=array;//Using pointer to point elements of array
int average=0;
int i,j;
//debug code to shows param1 points to array which has garage inside
int index =0 ;
for(index = 0; index < 6; index++){
printf("myDebug: %d\n", param1[index]);
}
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
*(param1+j)+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
*(param1+j)-=1;//decrement
}
}}

how can we return an array from a function in c? [duplicate]

This question already has answers here:
Returning an array using C
(8 answers)
Closed 7 years ago.
How can we return an array from a function i have no idea how to do this???
the are three cars and each is parked in a parking area for maximum 24 hours we have to find the cost for each car by making a function which wil evaluate the cost..??
#include <stdio.h>
#include <math.h>
#include <conio.h>
int calculateCharges(float hours[]);
int main() {
float hours[3];
int i;
for (i = 0; i <= 2; i++) {
printf("Enter the hours you parked for car : %d\n", i + 1);
scanf_s("%f", &hours[i]);
}
hours[i] = calculateCharges(hours[]);
printf("%-10s%-10s%-10s\n", "Cars", "Hours", "Charge");
for (i = 0;i <= 2;i++) {
printf("%-10d%-10.2f%-10.2f\n", i + 1, hours[i], calculateCharges(hours));
}
_getch();
return 0;
}
int calculateCharges(float hours[]) {
float cost[3];
int i;
for (i = 0; i <= 2; i++) {
if (hours[i] <= 3) { //if car parked for 3 or less hours it cost 2$
cost[i] = 2;
}
else if (hours[i] > 3 && hours[i] < 24) { //if car parked for more than 3 or less then 24 hours it cost 0.5$for each extra hour$
cost[i] = 2 + ((hours[i] - 3) / 2);
}
else if (hours[i] == 24) { //if hours = 24 hours 10$
cost[i] = 10;
}
else {
cost[i] = 0; //else its an error value zero cost
}
return cost[i];
}
}
You could pass in another array in which you return the cost, instead of making it a local array. Your method would look something like this:
int calculateCharges(float hours[], float costs[], int num) {
...
for(i=0;i<num;i++) {
...
costs[i] = 2;
Functions cannot return arrays, but they can return pointers, and they can modify caller-visible variables via pointer arguments. If you want a function to create an array and provide it to the caller, then that function would need to allocate the array dynamically (via malloc() or calloc()) and then use one of the methods I named to return a pointer to the first element of that array.
But as commenters also remarked, none of that appears to be needed for the problem you presented. As far as I can tell, you just need a function that computes one cost for one car. You can call such a function from inside a loop (even the same loop in which you read the input) to calculate the cost for each car, which the caller can then handle however is appropriate.

Max in array and its frequency

How do you write a function that finds max value in an array as well as the number of times the value appears in the array?
We have to use recursion to solve this problem.
So far i am thinking it should be something like this:
int findMax(int[] a, int head, int last)
{
int max = 0;
if (head == last) {
return a[head];
}
else if (a[head] < a[last]) {
count ++;
return findMax(a, head + 1, last);
}
}
i am not sure if this will return the absolute highest value though, and im not exactly sure how to change what i have
Setting the initial value of max to INT_MIN solves a number of issues. #Rerito
But the approach OP uses iterates through each member of the array and incurs a recursive call for each element. So if the array had 1000 int there would be about 1000 nested calls.
A divide and conquer approach:
If the array length is 0 or 1, handle it. Else find the max answer from the 1st and second halves. Combine the results as appropriate. By dividing by 2, the stack depth usage for a 1000 element array will not exceed 10 nested calls.
Note: In either approach, the number of calls is the same. The difference lies in the maximum degree of nesting. Using recursion where a simple for() loop would suffice is questionable. To conquer a more complex assessment is recursion's strength, hence this approach.
To find the max and its frequency using O(log2(length)) stack depth usage:
#include <stddef.h>
typedef struct {
int value;
size_t frequency; // `size_t` better to use that `int` for large arrays.
} value_freq;
value_freq findMax(const int *a, size_t length) {
value_freq vf;
if (length <= 1) {
if (length == 0) {
vf.value = INT_MIN; // Degenerate value if the array was size 0.
vf.frequency = 0;
} else {
vf.value = *a;
vf.frequency = 1;
}
} else {
size_t length1sthalf = length / 2;
vf = findMax(a, length1sthalf);
value_freq vf1 = findMax(&a[length1sthalf], length - length1sthalf);
if (vf1.value > vf.value)
return vf1;
if (vf.value == vf1.value)
vf.frequency += vf1.frequency;
}
return vf;
}
Your are not thaaaat far.
In order to save the frequency and the max you can keep a pointer to a structure, then just pass the pointer to the start of your array, the length you want to go through, and a pointer to this struct.
Keep in mind that you should use INT_MIN in limits.h as your initial max (see reset(maxfreq *) in the code below), as int can carry negative values.
The following code does the job recursively:
#include <limits.h>
typedef struct {
int max;
int freq;
} maxfreq;
void reset(maxfreq *mfreq){
mfreq->max = INT_MIN;
mfreq->freq = 0;
}
void findMax(int* a, int length, maxfreq *mfreq){
if(length>0){
if(*a == mfreq->max)
mfreq->freq++;
else if(*a > mfreq->max){
mfreq->freq = 1;
mfreq->max = *a;
}
findMax(a+1, length - 1, mfreq);
}
}
A call to findMax will recall itself as many times as the initial length plus one, each time incrementing the provided pointer and processing the corresponding element, so this is basically just going through all of the elements in a once, and no weird splitting.
this works fine with me :
#include <stdio.h>
#include <string.h>
// define a struct that contains the (max, freq) information
struct arrInfo
{
int max;
int count;
};
struct arrInfo maxArr(int * arr, int max, int size, int count)
{
int maxF;
struct arrInfo myArr;
if(size == 0) // to return from recursion we check the size left
{
myArr.max = max; // prepare the struct to output
myArr.count = count;
return(myArr);
}
if(*arr > max) // new maximum found
{
maxF = *arr; // update the max
count = 1; // initialize the frequency
}
else if (*arr == max) // same max encountered another time
{
maxF = max; // keep track of same max
count ++; // increase frequency
}
else // nothing changes
maxF = max; // keep track of max
arr++; // move the pointer to next element
size --; // decrease size by 1
return(maxArr(arr, maxF, size, count)); // recursion
}
int main()
{
struct arrInfo info; // return of the recursive function
// define an array
int arr[] = {8, 4, 8, 3, 7};
info = maxArr(arr, 0, 5, 1); // call with max=0 size=5 freq=1
printf("max = %d count = %d\n", info.max, info.count);
return 0;
}
when ran, it outputs :
max = 8 count = 3
Notice
In my code example I assumed the numbers to be positive (initializing max to 0), I don't know your requirements but you can elaborate.
The reqirements in your assignment are at least questionable. Just for reference, here is how this should be done in real code (to solve your assignment, refer to the other answers):
int findMax(int length, int* array, int* maxCount) {
int trash;
if(!maxCount) maxCount = &trash; //make sure we ignore it when a NULL pointer is passed in
*maxCount = 0;
int result = INT_MIN;
for(int i = 0; i < length; i++) {
if(array[i] > result) {
*maxCount = 1;
result = array[i];
} else if(array[i] == result) {
(*maxCount)++;
}
}
return result;
}
Always do things as straight forward as you can.

not getting the right counter inside my function array

function hot_days(), that has two parameters: the number of temperatures for the current month and an array in which the temperatures are stored. Search through the temp array and count all the days on which the noon temp exceeds 32. Return this count.
check my hot_days function in the end of the code. the icounter is not working and i think the problem is in the x < 32.
#include <stdio.h>
#include <conio.h>
#define HIGH 32
//function prototypes
void read_temps(int []);
void hot_days(int [], int []);
int main()
{
//Array
int TempsAry[31];
int hotAry[31];
//sending array
read_temps(TempsAry);
//sending hot array
hot_days(TempsAry, hotAry);
getch();
return 0;
}
void read_temps(int TempsAry [])
{
// variables
int tempnum ;
int x = 0 ;
int icount = 0;
while (x < 31)
{
// entering temperature
printf("Please enter today's temperature:\n ");
scanf("%d",&tempnum);
if (tempnum <= -500)
{
break;
}
TempsAry[x] = tempnum;
++x;
icount = icount +1;
}
//outputting array
for (x = 0 ; x<icount; ++x)
{
printf("%d\n",TempsAry[x]);
}
}
void hot_days(int TempsAry [], int hotAry [])
{
int x = 0 ;
int icount = 0;
while (x<31)
{
if (TempsAry[x] > HIGH)
{
hotAry[x] = TempsAry[x];
++icount;
}
++x;
}
printf("%d\n", icount);
}
There is nothing wrong in this code, its working properly. checkout the snippet at ideone.
while (x < 31)
{
// entering temperature
printf("Please enter today's temperature:\n ");
scanf("%d",&tempnum);
if (tempnum <= -500)
{
break;
}
here the loop breaks if you enter temprature <=-500. So if you entered value satisfying this condition as i'th temperature then the array temp_array[] will have garbage values after temp_array[i] since they will not be assigned value. This can result in your program to give random icount.
So make those remaining temp_array[] values 0.
You have a Sight issue with your code, If you're entering numbers less than 31, because the memory allocated for the array TempsAry[] contain raw values .So in function
void hot_days(int TempsAry [], int hotAry [])
the while loop
while (x<31)
{
if (TempsAry[x] > HIGH)
{
hotAry[x] = TempsAry[x];
++icount;
}
++x;
}
compares up to 31 elements even if the number of elements is less than 31, So this also includes the garbage values in the uninitialized memory, so the result obtained will be wrong
This can be eliminated by initializing the memory allocated for TempsAry to 0 in the main() function
int TempsAry[31];
int hotAry[31];
memset(TempsAry,0x00,sizeof(TempsAry));
You have uninitialized values in TempsAry. You are getting undefined behavior.
Change the line
int TempsAry[31];
to
int TempsAry[31] = {0};
which is equivalent to initializing with TempsAry with 31 comma separated zeros. More on that can be found at How to initialize an array in C

Resources