2017-04-02 80 views
-3
#include "stdio.h" 
#include "stdafx.h" 
#define _CRT_SECURE_NO_WARNINGS 
#define getch() _getch() 

struct Clicker { 
    int toggle; 
    int average; 
}; 

int main() 
{ 
    struct Clicker *clicker; 
    printf("Enter your toggle key: "); 
    (*clicker).toggle = _getch(); 
    printf("Enter your average cps: "); 
    scanf_s("%d", (*clicker).average); 
    printf("\nCurrent settings: \nToggle: %i \nAverage:%i\n", clicker->toggle, clicker->average); 
    getchar(); 
    return 1; 
} 

有代码。 错误:在C中创建一个小结构 - 有一些错误

'_getch' undefined, assuming extern returning int 
'scanf_s' format string '%d' requires an argument of type 'int *' but variadic arguemnt 1 has type int. 
uninitialized local variable 'clicker' used. 

我在做什么错?

+2

'_getch'在'conio.h'里,你没有包括 – StoryTeller

+1

关于编译器消息有什么不清楚? – melpomene

+2

这个程序的几乎每一行都有至少一个错误。你有没有一个教练,你可以一行一行地亲自检查吗?因为这要比试图在这里向你解释这一切要快得多和有效。 – zwol

回答

3

你说你试图通过自己学习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); 

不像scanfprintf取值,不是指针变量,所以这是正确的,只是我们要改变clicker->toggleclicker.toggleclicker->averageclicker.average因为clicker不再是一个指针。

在要打印的文本中,请勿在\n之前立即放置空格。

即使是现在,代码宽度也不应超过80列,因为这样可以同时在屏幕上并排显示两个代码文件,并且仍然使用合理的字体大小。当你在处理一个复杂的程序时,这是一个非常重要的事情。 (另外,真宽文字难读的总称。)

getchar(); 

这是不好的风格放到getchar呼叫立即节目结束之前。程序运行完毕后,应该退出。如果您的IDE在程序退出后拒绝保持“控制台”窗口,请让自己成为更好的IDE。

return 1; 

该计划没有失败,所以应该返回0,而不是1

+0

嗨,我非常感谢您的帮助。我完全理解你所说的一切 - 它确实与我一直在阅读的内容相匹配,我很高兴!我正在阅读关于如何在通过参数传递结构时仅仅创建副本的问题,因此您必须具有指针才能更改原始结构。非常感谢你。 – Spooker

+0

不客气,但我强烈建议你找到_someone_,你可以亲自谈谈'struct Clicker clicker;'和'struct Clicker * clicker;'的区别,直到你完全清楚你的脑袋。 – zwol

+0

我会环顾四周,寻找我所在地区的任何人。谢谢 – Spooker

0

使用的getchar()代替_getch()。另外,您不需要包含“stdafx.h”。删除它,避免包括你不需要的标题。

-1

好像你已经通过没有其使用真正了解不同的复制解决方案和片段创造了这个代码。

可能有使用_getch()的原因,但如果你现在不这样做,那么为什么你应该使用更多的标准解决方案,如getchar()

使用标准方法请考虑以下解决方案:

#include <stdio.h> // use <...> instead of "..." 
#include <stdlib.h> // for malloc() 
// #include "stdafx.h"  // not necessary  
// #define _CRT_SECURE_NO_WARNINGS // not necessary 
// #define getch() _getch() // not necessary 

struct Clicker { 
    int toggle; 
    int average; 
}; 

int main(){ 
    struct Clicker *clicker = malloc(sizeof(struct Clicker)); 
    printf("Enter your toggle key: "); 
    // (*clicker).toggle = _getch(); // use scanf() 
    scanf("%d",&clicker->toggle); 
    printf("Enter your average cps: "); 
    scanf("%d", &clicker->average); 
    printf("\nCurrent settings: \nToggle: %i \nAverage:%i\n",clicker->toggle, clicker->average); 
    // getchar(); // not nessecary 
    // return 1; // 1 is usually an error exit code, use 0 instead 
    return 0; 
} 

你似乎并不理解另一个事情是scanf()的正确使用。它收到一个指针(在这种情况下指向一个int)。由于您宣称clicker作为指向您的struct Clicker的指针,因此如果要访问其成员toggleaverage,则需要取消引用。你使用clicker->toggle来做到这一点。然后你需要一个指向这个解除引用的指针,你使用&

+2

呃,你没有修复最重要的错误 - 你仍然通过未初始化的指针读取和写入! – zwol

+0

Ups,你是完全正确的。希望我现在修好了。 – datell

+1

是的,除了如果你要打电话malloc你需要添加'#包括'。 – zwol