这是我的任务:编写一个程序,输入最多20个数字的两个正整数,并输出数字的总和。如果数字的总和超过20位,则使用适当的消息输出总和。您的程序必须至少包含一个函数来读取和存储数字到一个数组和另一个函数来输出数字的总和。 (提示:将数字作为字符串读取,并以相反的顺序存储数字的数字。)
我已经解决了很多问题,只是我的输出打印了每个索引的总和而不是一个多位数的整数。此外,我尝试添加代码以阻止用户输入超过20个字符但我收到有关字符串变量无法在此语句中使用的错误:if(user_str1> 20)
int read_strings(int arr1[], int arr2[])
{
string user_str1;
string user_str2;
cout << "enter a positive integer of, at most, 20 digits " << endl;
cin >> user_str1;
for (int ind2 = user_str1.length() - 1; ind2 >= 0; ind2--)
{
arr1[ind2] = static_cast<int>(user_str1[ind2]) - static_cast<int> ('0');
}
cout << "now enter a second number with the same conditions as the first " << endl;
cin >> user_str2;
for (int d = user_str2.length() - 1; d >= 0; d--)
{
arr2[d] = static_cast<int>(user_str2[d]) - static_cast<int>('0');
}
return user_str1.length();
}
void print_sum(int arr1[], int arr2[], int size)
{
string user_str1;
string user_str2;
int sum_arr[20];
int carry = 0;
for (int e = 0; e < size; e++)
{
if (arr1[e] + arr2[e] + carry > 9)
{
sum_arr[e] = arr1[e] + arr2[e] + carry;
sum_arr[e] = sum_arr[e] % 10;
carry = 1;
}
else
{
sum_arr[e] = arr1[e] + arr2[e] + carry;
carry = 0;
}
cout << "the sum of the two arrays is: " << sum_arr[e];
cout << endl;
}
}
int main(){
int arr1[20];
int arr2[20];
int size = read_strings(arr1, arr2);
print_sum(arr1, arr2, size);
return 0;
}
答案 0 :(得分:2)
c4018是一个警告,告诉您正在将签名号码与未签名号码进行比较。 e
是有符号整数,std :: string :: length返回无符号数(负字符串长度有什么意义?)。将e
的类型更改为无符号数字。
至于传递参数作为参考,你可能想要这样的东西:
void read_strings(string &user_string1, string &user_string2);
void print_sum(string &user_string1, string &user_string2);
// replace same-named local variables with the parameters
...
int main() {
string user_string1, user_string2;
read_strings(user_string1, user_string2);
print_sum(user_string1, user_string2);
// ...
}
答案 1 :(得分:1)
关于
“我不知道为什么我会在第63行收到警告c4018:
for (int e = 0; e < user_str1.length(); e++)
...那是因为您将签名的整数与相同或更大尺寸的 unsigned 整数进行比较,并且使用当前的C ++规则 - 据报道与原始规则不同 - 然后,有符号整数首先转换为无符号类型。如果它是负面的,那么这可以产生非常大的数字。例如,以下内容保证始终生成true
:
string( "Blah" ).length() < -3
非常反直觉,是吗?这就是编译器发出警告的原因。
一个简单的解决方法是将无符号整数转换为带符号的整数,或者使用此处的强制转换,或者通过定义一般大小和长度函数。这是演员:
for ( int e = 0; e < int( user_str1.length() ); e++ )
注1:通常最好避免使用强制转换,因为它们会告诉编译器你知道自己在做什么,并且通常会真正感知到演员的“需要”因为一个人真的不知道,然后是编译器,在错误的假设下工作,可以做邪恶的事情。
注意2:此语法不应用于指针或引用的强制转换,因为它可以根据所涉及的特定类型转换为不同类型的强制类型,这可以通过维护进行更改。对于指针或引用强制转换,使用命名的C ++强制转换。
RE
“此外,如何为两个函数创建参考参数,传递它们并将这些函数调用到主fxn
...首先请注意,这不是一个好主意。当函数返回某些信息时,只需让它返回该信息即可。不要考虑使用参考参数来优化(避免复制),至少在测量显示值的返回是一个关键瓶颈之前。在此之前执行此操作称为过早优化。伟大的计算机科学家唐纳德克努特曾经说过premature optimization is the root of all Evil™。作为程序员的任务主要不是向编译器传达要生成的机器代码。您的任务是以某种方式表达您想要的效果,以便稍后可以为其他人(或您自己!)轻松理解和修改代码,即与人类而不是编译器进行通信。
也就是说,函数read_strings
显然是在向用户询问两个ASCII数字串,并以两个数字值数组的形式将它们传回给调用代码。最好通过将数值数组作为函数结果返回来完成。这有两个问题:
原始数组不能直接作为函数结果返回,因此您需要一些包装器,使用例如直接std::vector
,或定义一个类,例如叫Large_int
。
当结果是一对read_strings
值时,函数名称Large_int
会产生误导。
出于您的目的,Large_int
的合理定义是
class Large_int
{
private:
vector<int> digits_;
public:
auto n_digits() const -> int { return digits_.size(); }
auto digit( int const i ) const -> int { return digits_[i]; }
auto to_string() const
-> string
{
// TODO:
}
void operator+=( Large_int const& other )
{
// TODO:
}
friend
auto operator+( Large_int const& a, Large_int const& b )
-> Large_int
{
Large_int result = a;
result += b;
return result;
}
Large_int() {}
Large_int( string const& digits )
{
// TODO:
// Throws exception if `digits` is an invalid spec.
}
};
所以而不是
void read_strings()
...你可以在技术上使用这样的参考参数:
void read_from_user( Large_int& a, Large_int& b )
...,但最好只返回一对:
auto ints_from_user() -> pair<Large_int, Large_int>
...其中pair
来自std::pair
标头<utility>
,并且函数命名(描述其结果)反映了新签名。
在main
功能中,您可以执行此操作。
pair<Large_int, Large_int> const numbers = ints_from_user();
cout << "The first number is " << numbers.first.to_string() << endl;
现在,在read_strings
代码中,有两种相同的尝试将类型化的规范转换为数字值数组。您最好为此定义一个函数。这不仅可以简化read_strings
,还可以避免重复代码的当前问题。重复的代码经常是重复的错误。大约80%的编程工作都是维护,当维护程序员必须找到并访问所有代码块的实例时,可能在这里和那里有小的变化,那么这不仅需要花费时间和金钱,而且可能会导致在一些新的错误介绍中,一些现有的错误被忽视了。
这称为关注点分离:让每个函数只做一件事,并做好这件事。它简化了事情。
在上面我假设转换函数是类Large_int
的构造函数。这反映了它的唯一目的:将规范转换为类型的值。
答案 2 :(得分:0)
main()
中定义两个大小为20的整数数组。我们说int num1[20]
和int num2[20]
void func(int* p1, int* p2)
并将其称为func(num1, num2)
读取数字时不需要辅助数组。做
arr1[a] = user_str1[ind1] - static_cast<int>('0');
#include <string>
并将字符串声明为std::string
。您的警告可能是那些未声明的字符串的结果答案 3 :(得分:0)
你在两个函数中声明的数组arr1[] and arr2[]
是不同的(即使它们具有相同的名称),并且声明它们的函数的作用域是局部的,字符串user_str1 and user_str2
也是如此,但你是对待它们,因为它们是相同的,会给你不正确的结果。一种方法是在主函数中声明数组并将其传递给其他函数,并且还需要更改这样的函数原型(假设两个数字中的数字相等):
void print_sum(int arr1[],int arr2[],int size);//takes two arrays of the same number of elements
int read_strings(int arr1[],int arr2[]);//takes two arrays,read the strings inside ,store then in the arrays and return the resulting number of elements in the arrays
并从您的两个功能中删除int arr1[20]
和int arr2[20]
声明。移除包含read_strings()
和arr1[a] = user_str1[ind1];a++;
的{{1}}函数中的循环,因为它们没有做任何有用的事情。
在arr2[c] = user_str2[ind3];c++;
功能中更改此内容:
read_strings()
要
int b=0;
for (int ind2 = user_str1.length() - 1; ind2 >= 0; ind2--)
{
arr1[b] = static_cast<int>(user_str1[b]) - static_cast<int>('0');
}
将for (int ind2 = user_str1.length() - 1; ind2 >= 0; ind2--)
{
arr1[ind2] = static_cast<int>(user_str1[ind2 ]) - static_cast<int>('0');
}
函数中的一个字符串的大小作为read_strings()
将return user_str1.length();
函数中的循环从print_sum()
更改为for (int e = 0; e < user_str1.length(); e++)
,将for (int e = 0; e < size; e++)
作为参数传递给函数。
然后你可以从main调用这些函数:
size