2013-03-24 2 views
0

На некоторой новой территории, работающей с указателями и ссылками, я пытаюсь передать массив по ссылке в функцию с помощью указателя, однако я продолжаю получать ошибки независимо от того, что я пытаюсь, я я уверен, что проблема очень проста в исправлении, но я просто не могу склонить голову вокруг нее, может ли кто-нибудь увидеть ошибку? любая помощь пройдет долгий путь благодаряПередача массива по ссылке с помощью указателей в C++

#include<iostream> 
#include<cmath> 
#include <iomanip> 
#include <cstdio> 
#include <cstdlib> 
#include <new> 

using namespace std; 

//Inline function 
inline double getFahrenheit(double theCelsius) 
{ 
//Convert the celcius to farenheit 
return (theCelsius + 32) * 5/9; 
} 

void outputWeather(double *temperaturesArray, const string WEEK_DAY_NAMES[], const  double MAX_NUMBER) 
{ 
    //this is a counter that will increment through the days and various 
    int counter; 
    //reset the counter to 0 so we can use it again  
    counter = 0; 
    //print a header  
    cout << "THIS WEEKS TEMPERATURE REPORT " << endl; 
    //print a divider 
    cout << "=============================" << endl; 
    //while the counter is less than 7 repeat again 
    while(counter < MAX_NUMBER) 
    { 
     //print out the temperatures by day   
     cout << WEEK_DAY_NAMES[counter] << "  " << temperaturesArray[counter] << "\370C " << getFahrenheit(temperaturesArray[counter]) <<"\370F "<< endl; 
     //increase the counter by 1 
     counter +=1; 
    } 
} 

//Function that will determine whether or not the value the user entered was numeric  and within the range 
double checkValidation(string weekDay) 
{ 
//Create a variable to store a valid number 
double validNumber; 

//This will hold the value for the lowest 
const double MIN_NUMBER = 1; 
//This will hold the value for the highest temperature 
const double MAX_NUMBER = 365; 
//This will hold the value for the valid number that the user will eventually enter 
validNumber = 0.0; 

//This will alert the user to enter a temperature for that day of the week 
cout << "Please enter the temperature for " << weekDay << endl; 
//This will take in teh value the user entered for teh temperature 
cin >> validNumber; 

    //If the text the user entered was not numeric start again    
if(cin.fail())    
{ 
    //C++ built in methods for clearing the cin      
    cin.clear();    
    fflush(stdin); 

    //alert the user what they typed was wrong 
    cout << "invalid input. please try again and enter a numeric value" << endl; 
    //pass in the weekeday and start over 
    checkValidation(weekDay);      
} 
else 
{ 
    //if teh number falls outside the range 
    if(validNumber < MIN_NUMBER || validNumber > MAX_NUMBER) 
    { 
     //Alert the user that it was outside the range   
     cout << "invalid input. please try again and enter a value between -90 and 60" << endl; 
     //pass in the weekday and try again   
     checkValidation(weekDay); 
    } 

} 
//return the valid number  
return validNumber; 

} 


int main() 
{ 
    //this is a counter that will increment through the days and various 
    int counter; 
    //a constant to hold the variable for the number of days 
    const int MAX_COUNTER = 7; 
    //an array that will hold all the days of the week 
    const string WEEK_DAY_NAMES[] = 
    { 
      "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" 
    }; 

    //this will hold all of teh temperatures 
    double temperaturesArray[MAX_COUNTER]; 
    //start the counter off at 0  
    counter = 0; 

    //begin telling the user to enter temperatures by printing a header 
    cout << "Please enter the temperature for every day of the week " << endl; 
    //while the counter is less than 7 we will repeat 
    while(counter < MAX_COUNTER) 
    {              
    //add temperature to the array 
    temperaturesArray[counter] = checkValidation(WEEK_DAY_NAMES[counter]); 
    //add 1 to the counter    
    counter +=1;      

    } 

    double * arrayPointer = new double[MAX_COUNTER]; 

    arrayPointer = &temperaturesArray; 

    outputWeather(arrayPointer, WEEK_DAY_NAMES, MAX_COUNTER);  

system("PAUSE"); 
return 0;    
} 
+0

какие ошибки вы получаете? – imulsion

+0

@imulsion текущий код говорит мне - не может преобразовать 'double (*) [7] 'в' double *' при назначении –

+0

Вы никогда не сможете передавать что-либо по ссылке «передавая указатель». Вы передаете вещи по ссылке, передавая * reference *. Если вы передадите указатель, вы передаете их указателем. – jalf

ответ

5

В C++ размер массива кодируется в его тип.

Нет общего типа «массив удвоений». Но существует «массив из 7 удваиваемых» типов и тип «массив из 13 удваиваемых» и т. Д.

Итак, чтобы передать массив в виде массива, а не просто как указатель на функцию, вам нужно закодировать точный тип в сигнатуре функции.

Это не будет «функция, которая принимает массив», а «функция, которая принимает массив размером 7».

Способ сделать это следующим образом:

void f(double (&arr)[7]); 

Или, конечно, вы можете шаблон его, если размер массива не является фиксированным:

template <size_t N> 
void f(double (&arr)[N]); 

Но на самом деле, что вы» Повторное выполнение не должно выполняться с использованием необработанных массивов.

Используйте стандартный библиотечный вектор.

0

Вкратце, заменяя линии

arrayPointer = &temperaturesArray; 

с

arrayPointer = temperaturesArray; 

делает код для компиляции.

Обратите внимание, что arrayPointer имеет тип double* и temperaturesArray имеет тип double[MAX_COUNTER] (с). Следовательно, вы можете назначить arrayPointer по адресу double, но вы не можете назначить arrayPointer по адресу double[MAX_COUNTER]. Это то, что пытался сделать оригинальный код, и, таким образом, он не смог скомпилировать.

С другой стороны, каждый элемент double[MAX_COUNTER] является double. В частности, первый элемент является double и вы можете назначить его адрес arrayPointer:

arrayPointer = &temperaturesArray[0]; 

Исправление выше всего synctatic сахара для этой линии. В самом деле, когда вы присвоить объект типа «массива типа Т» (например, double[MAX_COUNTER]) к «указателю типа Т», то компилятор выполняет так называемую массива для указателя преобразования что означает, что присваивает указателю первый элемент массива.

Теперь немного замечание о коде (с помощью прилагаемого исправления), в частности, следующие строки:

double * arrayPointer = new double[MAX_COUNTER]; 
arrayPointer = temperaturesArray; 

Первая строка выше выделяет память кучи для хранения массива MAX_COUNTER объектов типа double. Затем адрес первого элемента этого массива присваивается arrayPointer.

Затем следующая строка переназначает arrayPointer на адрес первого элемента temperaturesArray. Поэтому адрес первого элемента массива, выделенного кучей, теряется, и вы не можете больше delete. Помните, что каждый вызов new должен соответствовать вызову delete (в противном случае у вас есть утечка памяти). В этом конкретном случае, однако, лучше всего не звонить delete. Фактически, вы должны устранить вызов new, так как память кучи никогда не используется. Точнее, вы можете удалить первую строку выше.

Смежные вопросы