你说你试图通过自己学习C,所以我实际上将解释在这个程序中的所有错误。
#include "stdio.h"
stdio.h
应该总是使用<>
形式的#include
被包括在内。 (该""
形式是对于那些程序的一部分标头和<>
形式适用于来自系统提供的库头。在复杂的程序的区别会变得模糊,但不要担心现在。 )
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#define getch() _getch()
这三行都做特定于Windows的事情,在这样的程序中应该完全没有必要。删除它们。
struct Clicker {
int toggle;
int average;
};
这个结构定义没有错。
int main()
由于历史原因,您需要编写int main(void)
。这大多是无害的,但在C中写入空函数参数列表是一个不好的习惯。
{
struct Clicker *clicker;
这是你最重要的错误:你已经申报了指针到struct Clicker
,当什么看来你想是使用结构来声明一个局部变量。改为写struct Clicker clicker
。
指针是语言中最困难的方面之一,尤其是对人们新的节目。如果你的书没有专注于指针而没有其他内容,那么它就是一本不好的教科书,你需要得到一个更好的教科书。
printf("Enter your toggle key: ");
(*clicker).toggle = _getch();
与上述变化相一致,写clicker.toggle = ...
而不是(*clicker).toggle =
,因为你不再有一个指针。
不要使用非标准功能_getch()
,使用getchar()
代替。 (有实际需要使用_getch
程序,但这个是不是其中之一。)
printf("Enter your average cps: ");
scanf_s("%d", (*clicker).average);
在这里你有处理指针的地方。所有的参数scanf
,格式字符串后,必须在指针变量,因为这是它使scanf
写入变量。clicker
不再是一个指针,但即使我们没有做出改变,你写的也是错的,因为即使当clicker
是(*clicker).average
也不是指针。你需要写什么是
scanf("%d", &clicker.average);
的&
算到说带可变clicker.average
的地址,生产指针scanf
需求。
类似于我上面所说的关于_getch
,永远不会使用非标准功能scanf_s
。 (所有名称以_s
结尾的函数都来自Microsoft的一个善意但却灾难性的无效尝试,它们在标准C库中对许多设计错误进行了描述,在大多数操作系统中它们并不存在, t解决他们打算解决的问题,不要使用它们中的任何一个)
当你获得更多的经验时,你会意识到scanf
比它的价值更麻烦,但对于这样一个简单的程序,它是好。
printf("\nCurrent settings: \nToggle: %i \nAverage:%i\n",
clicker->toggle, clicker->average);
不像scanf
,printf
取值,不是指针变量,所以这是正确的,只是我们要改变clicker->toggle
到clicker.toggle
和clicker->average
到clicker.average
因为clicker
不再是一个指针。
在要打印的文本中,请勿在\n
之前立即放置空格。
即使是现在,代码宽度也不应超过80列,因为这样可以同时在屏幕上并排显示两个代码文件,并且仍然使用合理的字体大小。当你在处理一个复杂的程序时,这是一个非常重要的事情。 (另外,真宽文字难读的总称。)
getchar();
这是不好的风格放到getchar
呼叫立即节目结束之前。程序运行完毕后,应该退出。如果您的IDE在程序退出后拒绝保持“控制台”窗口,请让自己成为更好的IDE。
return 1;
该计划没有失败,所以应该返回0,而不是1
'_getch'在'conio.h'里,你没有包括 – StoryTeller
关于编译器消息有什么不清楚? – melpomene
这个程序的几乎每一行都有至少一个错误。你有没有一个教练,你可以一行一行地亲自检查吗?因为这要比试图在这里向你解释这一切要快得多和有效。 – zwol