2015-07-11 3 views
1

Я пытаюсь передать массив функции (* getcreditcurve). Я ожидаю, что функция (* getcreditcurve) вернет массив. Ожидается, что основная функция отправит несколько таких массивов в функцию (* getcreditcurve), ожидается, что функция указателя возвращает массив к основной функции для другого массива с использованием логики, указанной в функции указателя (* getcreditcurve). Я не получаю ошибку, но я не получаю правильное значение. Я ожидаю, что я + 1 будет 3 * 0,0039 = 0,0117 и I + 2 будет 4 * 0,0060 = 0,0024, однако я получаю следующее выходе первенствоватьНеожиданный возврат значения по переменной массива

'00D4F844 00D4F84C' 

Даже если изменить оператор печати на

'print << *(I1+1) << '\t' << *(I2+2) << endl;' 

я получаю следующее первенствует из положить

-9.26E+61 -9.26E+61 

Может кто-нибудь помочь в беде стрельба пожалуйста? Извините, я просмотрел другой пост/вопрос на этом сайте, но не смог получить простейший способ решить эту проблему. Я собираюсь использовать эту логику для создания других проектов, чтобы упростить вопрос только для решения основной проблемы.

#include<iostream> 
#include<cmath> 
#include<fstream> 
typedef double S1[5]; 
using namespace std; 
double *getcreditcurve(double *); 

int main() 
{ 


S1 C1 = { 0.0029, 0.0039, 0.0046, 0.0052, 0.0057 }; 
S1 C2 = { 0.0020, 0.0050, 0.0060, 0.0070, 0.0080 }; 

typedef double *issuer; 
issuer I1 = getcreditcurve(C1); 
issuer I2 = getcreditcurve(C2); 


ofstream print; 
print.open("result1.xls"); 
    print << (I1+1) << '\t' << (I2+2) << endl; 

    print.close(); 
    return 0; 


} 

double *getcreditcurve(S1 ptr) 
{ 
const int cp = 5; 
typedef double curve[cp]; 
curve h; 

h[0] = 2 * ptr[0]; 
h[1] = 3 * ptr[1]; 
h[2] = 4 * ptr[2]; 
h[3] = 5 * ptr[3]; 
h[4] = 6 * ptr[4]; 

return h; 
} 
+5

http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope Массивы не копируются неявно. Это одна из причин, по которой они не очень удобны и должны быть заменены на 'std :: array'. –

+0

[Объем и время жизни переменной] (http://stackoverflow.com/questions/11137516), кажется, почти дубликат ... сохранение указателя на переменную, которая вышла за рамки. –

ответ

1

Если вы хотите getcreditcurve возвращать массив, то попробуйте следующее:

const int cp = 5; 
typedef double curve[cp]; 
curve getcreditcurve(S1 ptr) { 

Но это дает ошибку error: ‘foo’ declared as function returning an array. Функции не могут возвращать C-массивы. Но хорошей новостью является то, что если вы полностью включите C++, вы можете вместо этого вернуть std::array.

#include<array> 
const int cp = 5; 
typedef curve std::array<double,cp>; 
curve getcreditcurve(S1 ptr) { 

Но на самом деле, std::vector, вероятно, гораздо лучше, так как у вас есть больше гибкости относительно размера.

#include<vector> 

std::vector<double> getcreditcurve(std::vector<double> ptr) 
{ 
    std::vector<double> h; 
    h.push_back(2 * ptr.at(0)); 
    h.push_back(3 * ptr.at(1)); 
    h.push_back(4 * ptr.at(2)); 
    h.push_back(5 * ptr.at(3)); 
    h.push_back(6 * ptr.at(4)); 

    return h; 
} 

На самом деле, почти все проблемы с массивами C могут быть решены с помощью std::vector. Затем в особых ситуациях вы можете использовать std::array. Но сосредоточьтесь на std::vector.

+0

ok Я попробую вектор, но только для подтверждения «typedef curve std :: array ;» или "std :: vector getcreditcurve (std :: vector ptr)" заключается в изменении функции кривой getcredit. Я написал мой проект ain с большим количеством массива. Sp больше пытается использовать массив, но концептуально массив и вектор будут работать одинаково (с учетом проблемы размера? – Kausik

+0

Вам нужно будет сделать еще много изменений. В принципе, вы должны избегать '*' полностью (кроме, конечно, для умножения). 'нужно написать 'vector C1 {0.0029, 0.0039, 0.0046, 0.0052, 0.0057};' также определить C1 как вектор. Я знаю, что это похоже на большую работу, но лучше просто избегать ' '-pointers в C++ –

+0

Кроме того, вы должны быть очень * понятны, когда используете слово« array ». Вы должны сказать« C-массив »при обсуждении типов массивов, которые вы используете теперь' eg char c [5] ', и вы должны сказать «' std :: array », когда говорите об улучшенных массивах в C++ 11. Я постараюсь быть ясным в будущем. Большинство людей, когда они говорят« массив », означают« массив C », но возможно, было бы лучше всегда быть ясным –

0

Невозможно вернуть массив C из функции. Есть другие вещи, которые вы можете вернуть, например std::vector или std::array. Вы должны подумать о перепроектировании своего приложения вокруг этих двух.

Но если вам действительно нужно использовать C-массивы в C++, я предлагаю, чтобы вместо того, чтобы пытаться вернуть массив из getcreditcurve, вы передаете дополнительный массив в getcreditcurve, который будет использоваться для сохранения результата. Это называется выходным параметром.

void getcreditcurve(double*, double *); 

Это решит проблему «объема». Затем вызывающий (main) создает массив перед вызовом getcreditcurve и затем передает это значение getcreditcurve. В результате getcreditcurve не несет ответственности за создание (или уничтожение) любого объекта.

double I1[5]; 
getcreditcurve(I1, C1); // will store its result on `I1`. 

Это может быть самый простой вариант, если вам действительно нужно как можно скорее запустить эту работу.

Если вы желаете внести некоторые дополнительные изменения, вы можете сделать гораздо более безопасную программу.Краткосрочная цель - отменить все виды использования * (за исключением использования его для умножения).

C массивы не могут передаваться по значению, в частности они не могут быть возвращены. Есть и другие напуганные вещи, которые вы можете сделать (передача специальных указателей), но самое лучшее, что можно сделать с массивами C, - передать их по ссылке. В C++ поведение, связанное с обращением, вполне последовательное и работает хорошо.

// http://stackoverflow.com/questions/31362360/unexpected-value-return-by-array-variable 
#include<iostream> 
#include<cmath> 
#include<fstream> 
typedef double S1[5]; 
using namespace std; 

/* In the following declaration, the two parameters 
* are taken by reference (note the '&'). 
* This is almost always the best way to pass arrays. 
* 
* Also, this is a template where N is automatically 
* set to the correct number of parameters. This nice 
* automatic behaviour is possible only because the 
* array is taken by reference. 
* 
* Finally, note that the second reference, for 'input', 
* has 'const'. This is to emphasize that 'input' is for input, 
* that getcreditcurve will not be allowed to modify the input argument. 
*/ 
template<size_t N> 
void getcreditcurve(double (&output)[N],const double (&input)[N]); 

int main() 
{ 


    /* S1 is the type - array of five doubles */ 
    /* Here declare and initialize C1 and C2 as two variables 
    * of this type */ 
    S1 C1 = { 0.0029, 0.0039, 0.0046, 0.0052, 0.0057 }; 
    S1 C2 = { 0.0020, 0.0050, 0.0060, 0.0070, 0.0080 }; 

    // create the two output arrays first, within main 
    S1 I1; 
    S1 I2; 
    // call getcreditcurve, passing in the output and input arrays 
    getcreditcurve(I1,C1); 
    getcreditcurve(I2,C2); 


    ofstream print; 

    /* you can't create Excel(.xls) files in C++ easily 
    * Better to just create a .csv file instead 
    * csv = comma-separated values 
    */ 
    print.open("result1.csv"); 
    print << I1[0] << ',' << I2[3] << endl; 

    print.close(); 
    return 0; 

} 

template<size_t N> 
void getcreditcurve(double (&output)[N],const double (&input)[N]) 
{ 
    output[0] = 2 * input[0]; 
    output[1] = 3 * input[1]; 
    output[2] = 4 * input[2]; 
    output[3] = 5 * input[3]; 
    output[4] = 6 * input[4]; 
} 

Но если серьезно, вы должны просто полностью свернуть C массивы. Это C++, а не C. Вместо этого используйте std::vector<double>.