Write a program to manipulate the temperature details as given below.
- Input the number of days to be calculated. – Main function
- Input temperature in Celsius – input function
- Convert the temperature from Celsius to Fahrenheit.- Separate function
- find the average temperature in Fahrenheit.
how can I make this program without initial size of array ??
#include<stdio.h>
#include<conio.h>
void input(int);
int temp[10];
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
In C arrays and pointers are closely related. In fact, by design an array is just a syntax convention for accessing a pointer to an allocated memory. *(see note for more details below)
So in C the statement
anyarray[n]
is the same as
*(anyarray+n)
Using pointer arithmetic.
You don't really have to worry about the details to make it "work" as it is designed to be somewhat intuitive.
Just create a pointer, and allocate the memory and then access it like as an array.
Here is some examples --
int *temp = null; // this will be our array
// allocate space for 10 items
temp = malloc(sizeof(int)*10);
// reference the first element of temp
temp[0] = 70;
// free the memory when done
free(temp);
Remember -- if you access outside of the allocated area you will have unknown effects.
To be clear it is the indexing operator ([ ]) that is translated to pointer arithmetic. This is not an array in the modern sense of the
type. Whether (or not) the pointer involved points to (dynamically) allocated
memory is inconsequential to how this operator works. In a more modern language you would be able to operate on the array as an abstract type (to see how big it is, for example), you can't do this in C.
An array without an initial size is basically just a pointer. In order to dynamically set the size of the array, you need to use the malloc() or calloc() functions. These will allocate a specified amount of bytes of memory.
In your code above, declare temp as an int pointer
int *temp;
Then allocate space for it using malloc() or calloc(). The argument that these functions take is is the number of bytes of memory to allocate. In this case, you want enough space for d ints. So...
temp = malloc(d * sizeof(int));
malloc returns a pointer to the first byte in the block of memory that was just allocated. Regular arrays are simply pointers to the first byte in a sectioned off block of memory, which is exactly what temp is now. Thus, you can treat the temp pointer as an array! Like so:
temp[1] = 10;
int foo = temp[1];
printf("%d", foo);
Outputs
10
You will need to declare temp as an int pointer (instead of an int array). Then, you can use malloc in your main (after your first scanf):
temp = malloc(d * sizeof(int));
If your compiler supports c99, then simply use VLA(variable length array).Use like this:
void input(int);
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
int temp[d];
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
Now temp[] is defined inside main() after date input.
1-add #include<stdlib.h> at the top of your file. Then modify the conv() code as follows:
2- modify temp declaration as follows (global variable):
int *temp;
3- modify input(int d) function as follows (tested on Visual Studio 2010):
void input(int d)
{
int x=0;
temp=(int*)malloc(sizeof(int)*d);
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
Allocate the "array" dynamically on the heap after you read the size.
I didn't change anything else so you may see it clearly.
#include<stdio.h>
#include<conio.h>
#include <stdlib.h> //here
void input(int);
int *temp=0; //here
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
temp=malloc(d * sizeof(int)); //here
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
Maybe it's late to answer but...
If you work with small embedded system you might not have malloc and free functions.
So you have to sacrifice memory for 366 * sizeof(your_type), define it statically and use as a circular buffer. Then you can always slice it by number of days you need to calculate an average value.
Of course this makes natural constrains. You can define it by yourself.
Related
I just started learning functions and passing the parameters. so i am kind of new to this. Here, in the following programming, i am changing the values of a[] which is a formal parameter. even though, the sort function is not returning anything. how are the elements in numberArray[] are getting sorted even though the sort function just dealing with the formal parameters?
#include<stdio.h>
void sort(int[],int);
int main(void)
{
int n;
printf("enter the number of elements : ");
scanf("%d",&n);
int numberArray[n];
printf("enter %d numbers :\n",n);
for(int i=0;i<n;i++)
scanf("%d",&numberArray[i]);
sort(numberArray,n);
printf("sorted list of numbers are :\n");
for(int i=0;i<n;i++)
printf("%d\n",numberArray[i]);
return 0;
}
void sort(int a[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
}
}
I would like to compare the above program with a simple program as follows.
#include<stdio.h>
void nothing(int);
int main(void)
{
int a;
printf("enter the value : ");
scanf("%d",&a);
nothing(a);
printf(" a = %d",a);
return 0;
}
void nothing(int b)
{
b=b+2;
}
In this program, the value of a is not changing. Why?
In C array parameters to functions are a fiction. Arrays don't get passed to functions; the parameter is treated as a pointer.
So in your example a is really an int*.
Personally, I think that function parameters declared as arrays is almost always a bad idea, since it doesn't model what is really being passed to the function. Until you understand what is really happening, it can cause confusion of the sort you ran into. It also commonly causes problems with people who try to obtain he size of the array passed to a function using the sizeof operator - that doesn't work since sizeof will return the size of a pointer type, not the actual array type.
The one situation where I think array formal arguments might make sense is with multi-dimension arrays, where the pointer arithmetic can be helpful.
Note that C99 introduced variable length arrays (VLAs) which can change much of this. VLAs are different animals, but because support for them came rather late (even after C99 was standardized, it took a while for may implementations to support them properly). This answer doesn't necessarily apply to passing VLAs as arguments to functions.
C passes by value ie
void nothing(int b) {
b=b+2;
}
is getting a copy of the integer. If you want to see the int change you need to pass it's address ie
void nothing(int *b) {
*b = *b + 2;
}
You pass the address as following
nothing(&a);
In the program you reference this function...
void sort(int a[],int n)
is taking a pointer to an array of integers as it's first argument so any change to it in the function changes the actual memory it points to
This program is to multiply every value of array by 10 using a function. I am getting a lot of errors.
Can I take size in for loop?
#include<stdio.h>
mult(int arr[])
{
int i;
for(i=0;i<size;i++)
{
arr*=10;
}
return arr;
}
int main()
{
int j[];
printf("enter the all ten values to multiply by 10");
for(j=0;j<size;j++)
scanf("%d");
j[] = mult(j);
printf("%d",&j);
return 0;
}
int j[]; You're creating an array wrongly (in this context). You have to specify its size. Eg.: int j[256];
for(j=0;j<size;j++) scanf("%d"); What's size? how can you increment an array?? You're using scanf wrongly. You should do for(int s=0;s<size;s++) scanf("%d",&j[s]);.
j[] = mult(j); is wrong again. You should create another array and copy values there.
printf("%d",&j); you don't need & here, remove it. You'd better use "%d\n" to print each number on its own line.
mult(int arr[]) function declared wrongly. You must specify a type your function returns. You may need to use int *mult(...) instead and return &arr[0];
arr*=10; what're you trying to achieve with this? Completely wrong, you're multiplying the address here.
Read the docs, please! Your code doesn't make any sense, please learn C first, then try to code.
Moreover, you'll need pointers here, pay attention to them. I'd advise you to write Hello World program first to just understand the basics. Mr. Kernighan and Mr. Ritchie will help you too.
Note: I may have missed some mistakes here as there are too many of them. Please correct me if so.
Here is a complete code learn the differences and correct your code:
#include<stdio.h>
void mult(int *arr,int size)
{
int i;
for(i=0;i<size;i++)
arr[i]*=10;
}
int main()
{
int size=10;
int j[size],i;
printf("enter the all ten values to multiply by 10\n");
for(i=0;i<size;i++)
scanf("%d",j+i);
mult(j,size);
for(i=0;i<size;i++)
printf("%d ",j[i]);
printf("\n");
return 0;
}
You must tell mult() what is the size of the array, and the array you are passing will be modified in mult() so you don't need to return a value.
mult(j, size);
and your mult() function
void mult(int *arr, size_t size)
{
int i;
for(i=0;i<size;i++)
{
arr[i] *= 10;
}
}
Apologies for this re-post as I do not know how to phrase my question as it is my first time using stack overflow. I hope someone could help me out in this quiz for my studies.
I had research on this program but I do not know if it relates to the quiz question on arraySize.
Question is below:
we pass array ai to function fillArray. What exactly is passed to the function? The answer is a single memory address, not the 10 integers! This is why we can use the function to fill the array ai with 10 numbers.
Complete the above function fillArray so that it reads arraySize number of integers from the user and fill the array with those numbers.
Write a driver program to test the function with integer arrays of different sizes.
Note the formal parameter int array[] in function fillArray can be changed to int *array. Verify this by modifying and testing your code.
My code is below:
#include <stdio.h>
#define MAX 10
int fillArray(int array[], int arraySize);
void print_intaray(int array[], int arraySize);
main()
{
int ai, exam_scores[MAX];
printf("***List of Array***\n\n");
ai = fillArray(exam_scores, MAX);
print_intaray(exam_scores, ai);
}
int fillArray(int array[], int arraySize)
{
int ai, count = 0;
printf("Type array, EOF to quit\n");
while ((count < arraySize) && (scanf("%d", &ai) !=EOF))
{
array[count] = ai;
count++;
}
return count;
}
void print_intaray(int array [], int arraySize)
{
int i;
printf("\n***Your Arrary***\n\n");
for (i = 0; i<arraySize; i++)
printf("%d\n", array[i]);
}
I'm new to programming and I hope my question could somehow be resolve.
Thanks for viewing :)
Assuming the question is "Why are int array[] and int *array equivalent in the function argument":
I'm not much of a C expert, but AFAIK arrays (in C) are largely just pointers to which you append a certain offset. Telling C you expect an int myarray[] means pretty much the same as expecting a pointer to an integer (int *array). If you increment the pointer, you can access the next element in the array. This is also known as pointer arithmetic.
The C compiler translates array syntax like foo[3] in the background to something like *(*foo+3), but you can also do that yourself by just dealing with the pointers.
I'm getting some input from the user in the main() function and create an array accordingly. Because of the nature of the location of this array it is not visible to other functions and I need to pass it to a few other functions for processing.
Is there any way to do this without allocating memory for it and passing a pointer to that allocated memory?
flight is structure typedef.
int main()
{
do{ // Read # of flights from user
printf("Enter max number of flights to read in from file\n");
printf("--> ");
fflush(stdin);
} while(!(scanf("%d",&num_of_flights)));
flight database[num_of_flights]; // Create database for flights
In C you can allocate memory during runtime in such way
#include <stdlib.h>
#include <stdio.h>
void print_array(int *array, int array_size){
for(int i = 0; i < array_size; ++i){
printf("%d ", *(array + i));
}
}
int main(){
int *array;
int array_size;
scanf("%d", &array_size);
array = malloc(sizeof(int) * array_size);
// Fill array with ints
for(int i = 0; i < array_size; i++){
*(array + i) = i;
}
print_array(array, array_size);
return 0;
}
This shows how you might use malloc on a struct and then use the malloc'd item as a parameter to other functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct fl {
int distance;
char aeroplane[30];
char startgeo[2];
};
typedef struct fl flight;
void show_flight_data(flight d) {
printf("distance %d aeroplane %s",d.distance, d.aeroplane);
}
int main()
{
int num_of_flights;
flight *database;
do{ // Read # of flights from user
printf("Enter max number of flights to read in from file\n");
printf("--> ");
fflush(stdin);
} while(!(scanf("%d",&num_of_flights)));
database=(flight *)malloc(sizeof(flight) * num_of_flights);
database[0].distance = 100;
database[1].distance = 200;
strcpy(database[0].aeroplane, "777");
strcpy(database[1].aeroplane, "Airbus");
show_flight_data(database[0]);
return(0);
}
From the C standard, 6.2.4 Storage durations of objects:
The lifetime of an object is the portion of program execution during
which storage is guaranteed to be reserved for it. An object exists,
has a constant address) and retains its last-stored value
throughout its lifetime....
An object whose identifier is declared with no linkage and without the
storage-class specifier static has automatic storage duration...
For such an object that does not have a variable length array type,
its lifetime extends from entry into the block with which it is
associated until execution of that block ends in any way.
So, the lifetime of database extends until the execution of its enclosing block ends. That block is the body of main, so it is alive until main returns or the program exits. Therefore, you can simply pass database to other functions, or even store its address in a global that is accessed by other functions ... there is no need to allocate space and copy it.
BTW, you should be aware that by defining database[num_of_flights], where num_of_flights is not a constant, you are using a relatively recent feature of C -- variable length arrays (VLA's) -- and that some prominent C compilers (cough, Visual Studio, cough) do not support them.
I need to pass the address of a pointer to a structure to a function, which inturn will dynamically allocate the memory for an array of structures and fill in the values.
Now from my calling method, once i return from the func1, i should be able to iterate through the array of structure and display the value of the structure variables.
Can someone explain how to pass the address of the pointer to the structure, also iterating through the array of structures created dynamically ?
my sample code looks like this:
struct test {
int a;
int b;
};
void func1(int *n,struct test **testobj)
{
n=5;
*testobj = (struct test*) malloc(n*sizeof(struct test));
for(i=0;i<n;i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
struct test testobj;int n;
func1(&n,&testobj);
for(i=0;i<n;i++)
{
printf("%d %d",(*testobj)[i].a,*testobj)[i].b);
}
free(testobj);
}
In main() define a pointer to a test structure:
struct test *testPtr;
To take the address of that pointer use the & address-of operator:
&testPtr;
This returns the address of the pointer and has type struct test **
You can then pass this into your function func1, which does the correct allocation (although casting malloc() is generally considered bad practice - Do I cast the result of malloc?). Other than that func1() looks good... the line...
*testobj = malloc(n*sizeof(struct test));
... is correct. *testobj dereferences your double pointer that you got by doing &testPtr, and stores the address of the new memory in your pointer. You are also correct when you dereference your double-pointer using (*testobj)[i] because [] has higher precedence than * you needed to (as you've correctly done) surround the dereference with brackets to make sure that happens before you take the index.
Thus, when func1() returns the pointer testPtr should now point to the array of n test structures you allocated and can be accessed using testPtr[i].a etc.
EDIT: Your for loop should become
for(i=0;i<n;i++)
printf("%d %d", testobj[i].a, testobj[i].b);
Your original for loop should have given you compilation errors? In the original code testobj is not a pointer, therefore dereferencing it should not be possible.
So the summary answer is in main() declare testobj as a pointer and then access the array elements as testobj[n] :)
EDIT: As eric has pointed out, remove n=5; from func1(). I think you meant *n=5 perhaps as some kind of debugging step... You probably mean to use n as the input to the function to say how many objects you want in your structure array. Either initialise n or perhaps re-define func1() to be
void func1(int n,struct test **testobj) // n is no longer a poitner, just a number
create your array of pointers to structures in declaration step itself and simply pass it to the function
struct test *testobj[10];
func1(&n,testobj);
This passes the whole array of pointers to the function
It isn't entirely clear which version you're asking for, but one of these should cover it:
/* allocate some number of tests.
*
* out_n: out parameter with array count
* returns: an array of tests
*/
struct test* allocate_some_tests(int *out_n) {
int n = 5; /* hardcoded, random or otherwise unknown to caller */
*out_n = n
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
/* allocate a specific number of tests.
*
* n: in parameter with desired array count
* returns: an array of tests
*/
struct test* allocate_n_tests(int n) {
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
Note that you can just return the allocated array, you don't need a pointer-to-pointer here.
As for calling them, and iterating over the result:
void print_tests(struct test *t, int n) {
for (; n--; t++)
printf("{%d, %d}\n", t->a, t->b);
}
int main()
{
int count1; /* I don't know how many yet */
struct test *array1 = allocate_some_tests(&count1);
print_tests(array1, count1);
int count2 = 3; /* I choose the number */
struct test *array2 = allocate_n_tests(count2);
print_tests(array2, count2);
}
Your code appears pretty much ok to me.
only edit that should make it fine is--
in place of
struct test testobj;
put the following code
struct test *testobj;
and keep the remaining as it is..!
here's the working version of what's required, here the memory is allocated in the called function just as required
#include <stdlib.h>
#include <stdio.h>
struct tests {
int a;
int b;
};
void func1(int *n,struct tests **testobj)
{
int i;
*n=5;
*testobj = (struct tests*) malloc((*n)*sizeof(struct tests));
for(i=0;i<(*n);i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
int i;
struct tests *testobj;int n;
func1(&n,&testobj);
for(i=0;i<(n);i++)
{
printf("%d %d",(testobj)[i].a,testobj[i].b);
}
free(testobj);
}