各位同事,我实在想不通问题出在哪里。
存在一个问题:
接受int n
; - 从控制台输入的序列中的实数个数。将所有数字显示为小数点后两位。例如:输入 - 3
4.123 7.011 5.1
// 3 - 数字的数量(<100),其余的是数字本身。
结论 -4.12 7.01 5.10
这是我得到的代码:
#include <stdio.h>
#include <stdlib.h>
main(){
int n=0,i=0;
double *pn;
scanf("%d",&n); // Принимаю кол-во чисел в последовательности
pn=(double *)malloc(n*sizeof(double)); // Присваиваю указатель на первый элемент блока
// из n-ячеек памяти размером double
while(i<n) // Гоняю цикл n-раз
scanf("%f",pn+i++); // После присваивания инкрементирую i для
// смещения в следующем цикле, по блоку памяти
// выделенным malloc
while(i>0){
printf("%.2f\n",*(pn + n - i--)); // Вывод чисел n-раз с 2-мя десятичными знаками
}
free(pn); // Освобождаю память, хотя, она и так
// освободится после выхода из программы,
// если я правильно понимаю.
}
结果如下:
如果我使用类型指示器 int *
并输入int
数字,将格式从 更改为"%f"
,"%d"
那么它似乎可以工作:
我不明白——为什么它不适用于实数?
我想了解指针和地址算术,所以我选择了这个解决方案。
编译代码:
int
之前沒有main
。不影响最大速度。n*sizeof(double)
混合了有符号和无符号算术。不影响最大速度。scanf
读取float
并写入double
。这是一个真正的问题,类型混淆了。如果你修复了所有三个错误,你将得到:
一个讽刺的问题:没有编译器编程难吗?
现在说说小事:
malloc
必要写sizeof(double)
。写成sizeof(*pn)
,这样就不会在两个地方重复类型。malloc
不需要给出,void *
它会double *
自动给出。pn+i++
和&pn[i++]
是等价的。但第一个通常表示以地址开头的数组pn+i++
,第二个表示一个元素的地址。如果遵循这个约定,阅读代码的程序员就更容易理解它是指向单个元素的指针还是指向数组的指针。for(int i = 0; i < n; ++i)
。n
可以不签名,演员阵容就会变少。以下是规范代码,标准 C 程序员更容易阅读和理解:
格式错误(对于 scanf 来说很重要)