Reputation: 117
I am currently in an introductory c++ class and am working assignment that sorts data. We recently covered structs and I decided to use structs to approach the problem rather than create 3 arrays to hold the information from our data file.
The trouble i'm having is when i'm trying to pass my struct to my function. Here is my error:
analyze_data.cpp: In function ‘int main()’:
analyze_data.cpp:76: error: conversion from ‘weather*’ to non-scalar type ‘weather’ requested
analyze_data.cpp: In function ‘int find_pos_of_smallest(weather, int, int)’:
analyze_data.cpp:110: error: no match for ‘operator[]’ in ‘data[pos]’
analyze_data.cpp:110: error: no match for ‘operator[]’ in ‘data[pos_of_smallest]’
I don't understand the error from line 76. I have done some research about passing structs to functions, and what i found was adding the "&" in the type declarations. However, i have no idea what it does or why i would need to do that as we haven't covered it in class. I also did try it, but i just got a different set of errors. So i figured i'd not post those and just start from what i know.
Here is my code
/*
Program name: Analyze data
Program discription: This program will read a data file named data.txt.
This data file is expected to be formated in a specific way and contain
specific weather information. The program will analyize this data and
return max, min temperatures, 'perfect days', how many cold fronts per
year, 10 coldest and hottest days in a year and finally find the 5
median days of the year.
Date: 10/1/2012
*/
#include <iostream>
#include <fstream>
using namespace std;
/*
* Declare struct's here
*
*/
struct weather
{
string date;
int high;
int low;
};
/*
* Forward declaration of a function. This declares the function,
* but does not define it. (Notice that there is no code, just
* a function header with a semicolon after it.
*
*/
int find_pos_of_smallest (weather data, int start_pos, int end_pos);
/* Our main function.
*
* Parameters:
* none
*
* Return value:
* 0 if we complete successfully, 1 if there was an error.
*/
int main()
{
//read the data file
ifstream weather_data("data.txt");
//declare array size, and then create array using struct
int days = 365;
weather data[days];
//store the data.txt in the array and then close the file
for (int i=0; i<days; i++)
{
weather_data >> data[i].date;
weather_data >> data[i].high;
weather_data >> data[i].low;
}
weather_data.close();
ofstream data_results ("results.txt");
// create the first 3 lines of the output reults in the following formated
data_results << "Assignment #5\n"
<< "CS 1410/2000\n"
<< "Jonathan Larsen\n";
/*
for(int i=0; i<3; i++)
{
cout<<data[i].date << " "<<data[i].high << " " << data[i].low<<endl;
}
cout<<endl;
*/
cout<<find_pos_of_smallest(data, 0, days)<<endl;
return 0; //no error so return a zero
}//end of program
/**** FUNCTIONS ****/
/* Write down exactly what the function will do (a postcondition).
* Write down what is required to use the function (any preconditions).
* Write down any other behavior or comments that will help a programmer.
*
* Parameters: (list parameters by type and name, and explain them)
* int example -- an example parameter
*
* Returns:
* double -- an example return value
*/
/* Returns the position of the smallest value found in the specified
* subarray. (Only the elements in the subarray
* between start_pos and end_pos inclusive are checked.)
*
* Parameters:
* d - a data array
* start_pos - the first position to check
* end_pos - the last position to check
*/
int find_pos_of_smallest (weather data, int start_pos, int end_pos)
{
int pos_of_smallest = start_pos;
for (int pos = start_pos+1; pos <= end_pos; pos++)
if (data[pos].low < data[pos_of_smallest].low)
pos_of_smallest = pos;
return pos_of_smallest;
}
Upvotes: 1
Views: 701
Reputation: 51226
Whenever you declare an array of something, like your data
array, writing the array's name by itself (in this case, data
) in subsequent code is, confusingly enough, actually equivalent to writing
&(data[0])
which means "the address of the first element of the data
array". This is how arrays are usually "passed" into functions in C and C++ -- by passing the address of their first element. It's done this way because the usual way of passing other types of arguments -- namely, copying them -- would be very wasteful in the case of large arrays. It also has the side-effect of allowing any changes that the function makes to the array to be visible to the calling code (sometimes this is needed, sometimes not).
How do you work with that address inside the function? You use a pointer-to-weather
:
int find_pos_of_smallest(weather* data, int start_pos, int end_pos)
A pointer is a variable that contains the address of some other thing. You can access the pointed-to thing using the *
indirection operator, the ->
operator (if the pointed-to thing is a struct
or class
), and, conveniently, the array subscripting operator []
: e.g. inside find_pos_of_smallest()
,
data[5]
refers to the sixth element in an array of weather
elements starting at the address stored inside the pointer data
.
Upvotes: 0
Reputation: 63461
You need to pass your array as a pointer:
int find_pos_of_smallest (weather *data, int start_pos, int end_pos)
Declaring the parameter as weather data
means just a single instance of the struct. Making it a pointer means you can pass an array (the pointer will get the address of the first element in the array, and when you index it with data[pos]
you will get the relevant element in that array).
Upvotes: 0
Reputation: 28302
You are passing an array to your function. Your function needs to either take type weather[]
or weather*
. For instance:
int find_pos_of_smallest (weather* data, int start_pos, int end_pos)
You should note that even if you were not passing an array but a regular struct, you should still pass by reference. Either pass a pointer (weather*) and use the dereference memeber operator (->) or pass by reference (weather&) and use the normal member operator(.). This is because passing by value (no */&) causes the struct to be copied into a new value on the stack which can take a considerable amount of time for large values (for instance if the string gets large).
Upvotes: 1