- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在写一个使用指针摊销的小程序
#include <stdio.h>
#include <string.h>
double power(double a, double b);
int main(void)
{
int loanAmount, number_of_payments, i = 0;
double interestRate, monthlyInterestRate, monthlyPayment;
printf("Enter amount of loan : $ ");
scanf(" %i",&loanAmount);
printf("Enter Interest rate per year : ");
scanf(" %lf",&interestRate);
printf("Enter number of payments : ");
scanf(" %i",&number_of_payments);
monthlyInterestRate = ((interestRate / 100) / 12); //AKA 'r' or rate.
monthlyPayment = (monthlyInterestRate) * (loanAmount/(1 - 1/(power((1 +
monthlyInterestRate), number_of_payments))));
double interest[7] = {0}; //Arbitrarily set to 7 - assuming less payments.
double principal[7] = {0};
double balance[7] = {0};
balance[0] = loanAmount;
double *ipoint,*ppoint,*bpoint,*bpointprev;
ipoint = &interest[0];
ppoint = &principal[0];
bpoint = &balance[0];
bpointprev = bpoint;
printf("Monthly payment should be $ %lf\n",monthlyPayment);
printf("# \t Payment \t Principal \t Interest \t Balance \n");
for (i = 1; i <= number_of_payments; i++) {
ipoint += i;
bpoint += i;
ppoint += i;
*ipoint = *bpointprev * monthlyInterestRate;
*ppoint = monthlyPayment - *ipoint;
*bpoint = *bpointprev - *ppoint;
printf("%i \t %.2f \t %.2f \t\t %.2f \t\t %.2f\n",i,monthlyPayment,*ppoint,*ipoint,*bpoint);
bpointprev += i; //Iterates after logic for next calculation.
}
return 0;
}
double power(double a, double b)
{
double i, sum = 1;
for (i = 0; i < b; i++) {
sum = sum * a;
}
return sum;
}
遇到了一个问题,我正在编写的 IDE 运行程序正常:
在 Cloud9 IDE 上:
但是在 Unix 终端上,我的 for 循环中的增量变量在似乎是任意计数之后跳转:
在 Unix 终端上:
我相当确定它与我四处游荡的所有指针引用有关,但我不知道为什么它会影响 for 循环中的 int 变量 i 或为什么 IDE 会处理错误干净地。请多多指教!
最佳答案
您的代码存在大量问题,它们正等着引起问题。正如您所发现的,您未能通过使用 ptr += i
递增指针来保护数组边界。导致您通过访问和写入数组存储之外的内存来调用未定义的行为。
以interest
为例和 ipoint
:
double interest[7] = {0};
ipoint = &interest[0];
因此您的索引在 interest
内数组如下和ipoint
初始化为指向 interest
中的第一个元素:
+---+---+---+---+---+---+---+
interest | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
+---+---+---+---+---+---+---+
^
|
ipoint
在你的循环中你正在前进 ipoint += i
.在循环的第一次迭代中,您前进了 ipoint
一个:
+---+---+---+---+---+---+---+
interest | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
+---+---+---+---+---+---+---+
^
|
ipoint
你的第二次迭代,你前进了两倍:
+---+---+---+---+---+---+---+
interest | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
+---+---+---+---+---+---+---+
^
|
ipoint
你的第三次迭代,你前进了三:
+---+---+---+---+---+---+---+
interest | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
+---+---+---+---+---+---+---+
^
|
ipoint
当 i = 4
你提前ipoint
超出数组末尾,并在为 ipoint
赋值时调用未定义行为并尝试将值存储在您不拥有的内存中:
+---+---+---+---+---+---+---+---+---+---+---+
interest | 0 | 1 | 2 | 3 | 4 | 5 | 6 | out of bounds |
+---+---+---+---+---+---+---+---+---+---+---+
^
|
ipoint
注意:当未定义的行为被调用时,您的代码可能看起来正常工作,或者它可以 SEGFAULT
(或介于两者之间的任何东西),您的代码操作只是未定义,从那时起就不能依赖了。
您需要做的是将每个指针前进 1
, 不是 'i'
.这将确保您不会超出数组范围进行写入。您可以通过简单地更改 'i'
来解决问题。至 1
对于每个,例如
ipoint += 1;
bpoint += 1;
ppoint += 1;
还有许多其他地方可能会引发未定义行为。您未能检查 scanf
的返回 .如果您输入(不小心,或键盘的猫步)不是数字值,匹配失败将发生,将不会从stdin
中读取任何字符。并且将跳过所有进一步的提示,然后您将继续处理不确定值,这将调用未定义的行为。
此外,如果输入超过 7
对于 number_of_payments
或者您调用未定义行为 的小于零的值。 (number_of_payments = 0
的结果也相当无趣)当接受输入时,您不仅必须验证转换是否成功,还必须验证结果值是否在可用范围内——以避免未定义的行为,例如
printf ("Enter number of payments : ");
if (scanf (" %i", &number_of_payments) != 1) {
fprintf (stderr, "error: invalide no. of payments.\n");
return 1;
}
/* validate no. pmts in range */
if (number_of_payments < 1 || number_of_payments > MAXPMTS) {
fprintf (stderr, "error: no. of payments exceed MAXPMTS (%d)\n",
MAXPMTS);
return 1;
}
最后,您可以自由地初始化 ipoint = &interest[0];
, 没有必要。访问数组时,数组被转换为指向其第一个元素的指针,因此 ipoint = interest;
是所有需要的。下面的评论中还解决了其他问题,但总而言之,您可以执行类似以下操作以确保在整个代码中定义行为:
#include <stdio.h>
#include <string.h>
#define MAXPMTS 32 /* if you need a constant, define one (or more) */
double power (double a, double b);
int main (void)
{
int loanAmount = 0, /* initialize all variables */
number_of_payments = 0,
i = 0;
double interestRate = 0.0,
monthlyInterestRate = 0.0,
monthlyPayment = 0.0;
/* numeric conversions consume leading whitespace (as does %s)
* the ' ' in the conversion doesn't hurt, but isn't required.
*/
printf ("Enter amount of loan : $ ");
if (scanf (" %i", &loanAmount) != 1) { /* validate conversion */
fprintf (stderr, "error: invalid loan amount.\n");
return 1;
}
printf ("Enter Interest rate per year : ");
if (scanf (" %lf", &interestRate) != 1) {
fprintf (stderr, "error: invalid interest rate.\n");
return 1;
}
printf ("Enter number of payments : ");
if (scanf (" %i", &number_of_payments) != 1) {
fprintf (stderr, "error: invalide no. of payments.\n");
return 1;
}
/* validate no. pmts in range */
if (number_of_payments < 1 || number_of_payments > MAXPMTS) {
fprintf (stderr, "error: no. of payments exceed MAXPMTS (%d)\n",
MAXPMTS);
return 1;
}
monthlyInterestRate = ((interestRate / 100) / 12); //AKA 'r' or rate.
monthlyPayment = (monthlyInterestRate) * (loanAmount/(1 - 1/(power((1 +
monthlyInterestRate), number_of_payments))));
double interest[MAXPMTS] = {0};
double principal[MAXPMTS] = {0};
double balance[MAXPMTS] = {0};
balance[0] = loanAmount;
double *ipoint = NULL,
*ppoint = NULL,
*bpoint = NULL,
*bpointprev = NULL;
ipoint = interest;
ppoint = principal;
bpoint = balance;
bpointprev = bpoint;
printf ("Monthly payment should be $ %lf\n", monthlyPayment);
printf ("# \t Payment \t Principal \t Interest \t Balance \n");
/* standard loop is from 0 to i < number_of_payments */
for (i = 0; i < number_of_payments; i++) {
ipoint += 1;
bpoint += 1;
ppoint += 1;
*ipoint = *bpointprev * monthlyInterestRate;
*ppoint = monthlyPayment - *ipoint;
*bpoint = *bpointprev - *ppoint;
/* adjust 'i + 1' for payment no. output */
printf ("%i \t %.2f \t %.2f \t %.2f \t\t %.2f\n",
i + 1, monthlyPayment, *ppoint, *ipoint, *bpoint);
bpointprev += 1; //Iterates after logic for next calculation.
}
return 0;
}
double power(double a, double b)
{
double i, sum = 1;
for (i = 0; i < b; i++) {
sum = sum * a;
}
return sum;
}
(注意:您是从 i=1
循环到 i <= number_of_payments
还是从 i=0
循环到 i < number_of_payments
很大程度上取决于您,但循环变量跟踪保护数组边界的有效数组索引。如上所述,支付编号的输出只需调整 i + 1
即可生成所需的 1,2,3...
)
(另请注意:在实践中,您要避免对货币使用浮点数学。当您因舍入错误而亏损时,人们会非常沮丧。整数数学消除了这个问题)
仔细检查一下,如果您还有其他问题,请告诉我。
关于c - 为什么我的 for 循环增量变化很大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51406889/
嘿伙计们。 实现背景变化(基本上是幻灯片放映)和过渡效果的常见方法有哪些。我想每隔一段时间改变complte文档背景。 我是一名 ASP.net 开发人员,并且希望大部分内容都可以在 ASP 中实现。
也许,指针已经在修改过程中指向 auto_ptr 的常规指针指向 unique_ptr 和 shared_ptr 我只是想知道已经开发出来的新型指针是否完全覆盖了旧版本(或者您可能认为存在内存泄漏问题
我使用 Android Studio 构建 Android 应用。 我的问题是:当 fragment 改变时,应用程序崩溃。 控制台输出[控制台] 01-06 18:35:21.952 27756-
****澄清**我做了这个 [Fiddle] ( http://jsfiddle.net/sggPv/10/ ) 来帮助澄清情况。 该脚本起初适用于两个表格,但随后当您点击 slider 并将新表格加
我有图标,单击它会将新的 div(列)添加到 div 容器。问题是,当新的 div(列)出现时,按钮不会向右移动。是否可以以某种方式仅在 div 内添加 position:fixed? 这是我的几个屏
我是 Java 新手,继承了现有的 Android 应用程序。原始开发人员选择使用常量接口(interface)。 我的问题是我需要更改其中一些常量来编译生产应用程序与开发应用程序。如果我手动修改一些
在 Apple developer Document 中,我在 UIColor 中发现了一些新东西。 If your app was linked on or after iOS 10 and whe
我没有经常使用 ShareKit,但我只想拥有三个共享选项:Facebook、Twitter 和电子邮件。 ShareKit 提供了更多选项,包括更多按钮。但是,我不想要“更多”选项,只想要三个。 在
我正在构建一个 JS 库,其中一个用例要求我在 DOM 更改时触发一个事件,特别是如果它是一个单页应用程序,例如:github search bar 经过一番研究,我遇到了MutationObserv
我已经设法编写了一个代码来检测任何工作表中特定单元格的值变化,但我一直在努力构建检测和跟踪范围(值)变化的东西。 例如,如果用户决定复制和粘贴某个范围的数据(假设超过 1 个单元格),它不会被宏捕获。
使用 ffmpeg ,我们可以对音频电平进行多少控制?例如,我想在程序的时间轴上映射一个“M”形: t0 - t1 : fade in from 0 to 1 t1 - t2 : play at fu
使用 jQuery 1.7.1,我尝试为下拉列表上的更改事件创建一个事件处理程序。下拉列表会动态添加到 DOM 中。似乎在大多数浏览器上都能很好地工作,但是哦,奇怪的 IE8 想要变得困难。有解决方法
我想制作一个具有可选边框大小的自定义控件。请参阅下面的代码。边框绘制在非客户区,其宽度可以是 0、1 或 2 像素。我已经在 WM_NCPAINT 中成功完成了边框绘制。问题是,在更改控制边框大小的属
我知道这个问题之前已经被问过,而且我实际上已经找到了一些我已经实现的解决方案。不幸的是,我没能得到我想要的。 我以前没有做过AngularJS,我想做的是: 检测网址何时更改 根据网址更改的内容进行一
我有一个 auto-carousel 指令,它循环访问链接元素的子元素。 但是,子级尚未加载到 DOM 中,因为它们的 ng-if 表达式尚未解析。 如何确保父指令知道其 DOM 树已发生更改?
我有一个流程可以通过内容提供商从数据库中获取数据。 fun getDataFlow(): Flow { return flow { emit(Result.Loading)
我有一些有效的代码,但有时它只是“跳转”到其他文本而不考虑间隔。 该代码基本上按时间间隔更改标题的文本。 var text = ["text1", "text2", "text3","text4","
我正在尝试将 onCLick 监听器添加到我的 PreferenceScreen 上的开关,但它不起作用。我尝试了 Java 教程中的代码并将其转换为 Kotlin,但由于某种原因它无法正常工作。 这
我们目前正在尝试升级我们的程序使用的 ffmpeg 版本。跳跃很大,因为我们目前使用的是 ffmpeg 0.8,最新版本是 1.2。 在这些测试中,我使用的是(让我说)我发现的令人惊叹的软件包 her
我有一个流程可以通过内容提供商从数据库中获取数据。 fun getDataFlow(): Flow { return flow { emit(Result.Loading)
我是一名优秀的程序员,十分优秀!