#c
#c
Вопрос:
… это то, что я хочу сделать. У меня есть следующий код:
...
int len = 0;
char c;
bool fp = false;
while (infile.good()) {
c = infile.get();
if (c == 'n') len;
else if (c == '.') fp = true;
}
if (fp == true){
float Ai[N];
float *Ao = new float [len];
} else {
int Ai[N];
int *Ao = new int [len];
}
for (int i=0; i<L; i){
for (int j=0; j<N; j) infile >> Ai[j];
Ao[i] = findmax(Ai);
}
...
Предполагается, что массив состоит из двойных чисел, если в файле обнаружена десятичная точка, или, если нет, из целых чисел.
Я еще не проверял первый цикл, потому что я не получил его для компиляции:
warning: unused variable ‘Ai’
warning: unused variable ‘Ao’
warning: unused variable ‘Ai’
warning: unused variable ‘Ao’
error: ‘Ai’ was not declared in this scope
error: ‘Ao’ was not declared in this scope
Я полагаю, что у меня есть фундаментальная проблема с тем, как справиться с этой задачей, а не просто простая ошибка.
Итак, что не так и как исправить / исправить это с самого начала?
Комментарии:
1. Ai и Ao выходят из области видимости после завершения блока if
2. Лишь немного связано с вашим вопросом: циклы ввода, подобные вашему, часто содержат ошибки. Попробуйте
while(infile.get(c)) { ... }
читать входные данные по одному символу за раз.
Ответ №1:
Редактировать: как указано выше, ваша ошибка компилятора возникает из-за того, что Ao и Ai объявляются в области, отличной от той, в которой вы пытаетесь их использовать.
Вот где шаблоны действительно пригодятся.
template<typename T>
T *findMaxes(inFile)
{
T Ai[N];
T *Ao = new T[len];
for (int i = 0; i < L; i)
{
for (int j = 0; j < N; j)
infile >> Ai[j];
Ao[i] = findmax(Ai);
}
return Ao;
}
int len = 0;
char c;
bool fp = false;
while (infile.good()) {
c = infile.get();
if (c == 'n') len;
else if (c == '.') fp = true;
}
if (fp)
{
float *Ao = findMaxes<float>(inFile);
// Do stuff with the floating point array
}
else
{
int *Ao = findMaxes<int>(inFile);
// Do stuff with the int array
}
Ответ №2:
Короткий ответ: вы не можете этого сделать.
C — это статически типизированный язык, что означает, что вы должны определить тип переменной во время компиляции (т. Е. При написании кода). Вы не можете сказать что-то вроде «объявить x
тип get_type_from_user()
.
С помощью полиморфизма на основе наследования вы можете настроить некоторые настройки, в которых вы обрабатываете все через ссылку на базовый класс, но фактический тип экземпляра определяется во время выполнения. Я полагаю, это почти определенно излишне для вашей установки, но это стандартный способ обработки зависимостей времени выполнения от деталей в C . Однако это не работает для примитивных типов, которые не относятся к типу class .
Вот наивный пример излишнего удаления типов:
class NumberImpl;
class Number
{
NumberImpl * pNum;
public:
explicit Number(int n) : pNum(new NumberInteger(n)) { }
explicit Number(double d) : pNum(new NumberDouble(d)) { }
// ..
};
class NumberImpl { /* ... common implementation interface here ... */ }
class NumberInteger : public NumberImpl
{
int n;
public:
NumberInteger(int m) : n(m) { }
// ...
};
// and so forth
Этот вид стирания типов используется boost.any
shared_ptr
постоянно, и у него есть некоторые преимущества. Нужно ли вам это, зависит от вас (но ответ «нет»), и вы, вероятно, можете довольствоваться только одним общим числовым типом. Если вы это сделаете long double
, вы обычно получаете 64 бита интегральной точности плюс тонны диапазона масштаба.
Ответ №3:
ваша проблема связана с областью действия .. если вы объявите переменную внутри блока if, она будет существовать только внутри этого блока. К тому времени, когда вы доберетесь до своего последнего цикла for , Ao больше не существует. Вы могли бы попробовать это:
if (fp == true)
{
float Ai[N];
float *Ao = new float [len];
for (int i=0; i<L; i)
{
for (int j=0; j<N; j) infile >> Ai[j];
Ao[i] = findmax(Ai);
}
}
else
{
int Ai[N];
int *Ao = new int [len];
for (int i=0; i<L; i)
{
for (int j=0; j<N; j) infile >> Ai[j];
Ao[i] = findmax(Ai);
}
}
Ответ №4:
Вы правы в отношении фундаментальной проблемы здесь. Ваши переменные Ai выходят за пределы области видимости при завершении «}». Таким образом, вам больше не разрешается использовать их впоследствии. Это также объясняет предупреждения, потому что вы никогда не используете эти переменные до их исчезновения.
C имеет статическую типизацию, поэтому вы не можете просто изменить тип переменных во время выполнения.
Вы могли бы изучить объединения, чтобы поместить в переменную либо float, либо int . Подход, более близкий к C , может включать наследование. Но вы могли бы с таким же успехом дублировать код (duck), если у вас есть только эти два случая.
Комментарии:
1. аргумент… по крайней мере, предложите использовать typesafe, гарантирующий строгое исключение boost::variant<…> вместо простых объединений ( здесь )
2. Согласен. Это гораздо более приятное решение проблемы.