首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

C语言中一个奇怪的小疑点-求解

2013-07-04 
C语言中一个奇怪的小问题------求解前些天一个小弟让我给他弄个C语言的东东,要求如下:0 欢迎!本程序用于测

C语言中一个奇怪的小问题------求解
前些天一个小弟让我给他弄个C语言的东东,要求如下:
0 欢迎!本程序用于测试题得分统计,最多支持1000题,每题最多10个选项
1 由用户输入题目数,选项数,每个选项的分数(每个选项都有相应的分数)
2 选项分为字母选项或数字选项
3 支持将选项分为多个类别,并打印出每个类别分数的总和
样例输入和输出:
选项为字母(1)或数字(2):1 
请输入题目数:10
请输入选项数:4
请输入选项:A B C D
请依次输入每个选项的得分:1 2 3 4
请输入选择:A B C D A B C D A B
要将题目分为几个类别:2
请输入类别1的选项数和选项:5 1 2 3 4 5
请输入类别2的选项数和选项:5 2 4 6 8 10
类别1得分:11
类别2得分:12
写倒是很快写好了,但是有点小问题,那个选项第二个的标号或者分数总出问题(只有第二个),
试了几个方法,注释掉的都试过了,代码如下,各位给看看,求解,很谢谢。。。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
int exerciseCount = 0, optionCount = 0, typeCount = 0, optionType = 0, 
groupCount = 0, groupOptionCount = 0, groupScoreSum= 0;
void* options = NULL;
void* chooses = NULL; 
//int* optionScores = NULL;
int* groupChooses = NULL;
int* groupScores = NULL;  
printf("\
**************************************\n \
*                欢迎!              *\n \
*      本程序用于测试题得分统计,    *\n \
*  最多支持1000题,每题最多10个选项  *\n \
**************************************\n");

printf("选项为字母(1)或数字(2),请选择类型:");
scanf("%d", &optionType);
switch(optionType)
{
case 1:    printf("选项为字母!\n");    break;
case 2:    printf("选项为数字!\n");    break;
default:   printf("非法选项!\n");      exit(0);
}

printf("请输入题目数:");
scanf("%d", &exerciseCount);

printf("请输入每题的选项数:");
scanf("%d", &optionCount);

// 存储选项标号数组
if(optionType == 1)
{
    printf("请依次输入选项标号(请注意标号为字母):");
options = (char *) malloc(sizeof(char)*optionCount);
for(int i=0; i<optionCount; ++i)
{
scanf(" %c", (char *)options + sizeof(char)*i);
}
}
else if(optionType == 2)
{
    printf("请依次输入选项标号(请注意标号为数字):");
 options = (int *) malloc(sizeof(int)*optionCount); 
for(int i=0; i<optionCount; ++i)
{
scanf("%d", (int *)options + sizeof(int)*i);


}
}

// 存储选项标号对应分数数组 
    printf("请依次输入选项标号对应的分数(必须为数字):");
//optionScores = (int *) malloc(sizeof(int)*optionCount);
int optionScores[10] = {0};
int d = 0; 
char *str = NULL; 
for(int i=0; i<optionCount; ++i)
{
scanf("%d", &d);
memmove(&optionScores[i], &d, sizeof(int));
optionScores[i] = atoi(gets(str));
//optionScores[i] = d;
//scanf("%d", optionScores + sizeof(int)*i);
//scanf("%d", &optionScores[i]);

    
    // 存储选择答案数组 
if(optionType == 1)
{
    printf("请依次输入每题答案标号(请注意输入的标号必须为字母):\n");
chooses = (char *) malloc(sizeof(char)*exerciseCount);
for(int i=0; i<exerciseCount; ++i)
{
scanf(" %c", (char *)chooses + sizeof(char)*i);
}
}
else if(optionType == 2)
{
    printf("请依次输入每题答案标号(请注意输入的标号必须为数字):\n");
chooses = (int *) malloc(sizeof(int)*exerciseCount);
for(int i=0; i<exerciseCount; ++i)
{
scanf("%d", (int *)chooses + sizeof(int)*i);
}
}

// 打印存储,用以查看,可以屏蔽 
if(optionType == 1)
{
for(int i=0; i<optionCount; ++i)
{
 //printf("%c:%d\n", *((char *)options + sizeof(char)*i), *(optionScores + sizeof(int)*i));
 printf("%c:%d\n", *((char *)options + sizeof(char)*i), optionScores[i]);
}
}
else if(optionType == 2)
{
for(int i=0; i<optionCount; ++i)
{
 //printf("%d:%d\n", *((int *)options + sizeof(int)*i), *(optionScores + sizeof(int)*i));
 printf("%d:%d\n", *((int *)options + sizeof(int)*i), optionScores[i]);
}
}

if(optionType == 1)
{
for(int i=0; i<exerciseCount; ++i)
{
 printf("%d:%c\n", i+1, *((char *)chooses + sizeof(char)*i));
}
}
else if(optionType == 2)
{
for(int i=0; i<exerciseCount; ++i)
{
 printf("%d:%d\n", i+1, *((int *)chooses + sizeof(int)*i));
}
}

printf("要将题目分为几个类别:");
scanf("%d", &groupCount);
groupScores = (int *) malloc(sizeof(int)*groupCount);   


for(int i = 0; i < groupCount; ++i)
{
printf("请输入类别%d的选项数:", i+1);
scanf("%d", &groupOptionCount);
groupChooses = (int *) realloc(groupChooses, sizeof(int)*(groupOptionCount));

printf("请输入类别%d的选项(题标大于0并且题数为%d):", i+1, groupOptionCount);
int groupChoose = 0;
        int groupScoreSum = 0;
for(int j=0; j<groupOptionCount; ++j)
{
scanf("%d", &groupChoose);
if(optionType == 1)
{
for(int k=0; k<optionCount; ++k)
{
if(*((char *)chooses + sizeof(char)*(groupChoose-1)) == *((char *)options + sizeof(char)*k))
{
//groupScoreSum += *(optionScores + sizeof(int)*k);
groupScoreSum += optionScores[k];
}
}
}
else if(optionType == 2)
{
for(int k=0; k<optionCount; ++k)
{
if(*((int *)chooses + sizeof(int)*(groupChoose-1)) == *((int *)options + sizeof(int)*k))
{
//groupScoreSum += *(optionScores + sizeof(int)*k);
groupScoreSum += optionScores[k];
}
}
}
}
*(groupScores + sizeof(int)*i) = groupScoreSum;
}

for(int i = 0; i < groupCount; ++i)
{
printf("类别%d的得分:%d\n", i+1, *(groupScores + sizeof(int)*i));
}

free(options);
options = NULL;
free(chooses);
chooses = NULL;
//free(optionScores);
//optionScores = NULL;
free(groupChooses);
groupChooses = NULL;
free(groupScores);
groupScores = NULL;

return 0;
}

C 存储 指针
[解决办法]
引用:
Quote: 引用:

读入这里没有问题,是你的指针运算有问题,造成大量的访问越界,表现灵异
指针加1不是增加一个字节,而是增加指向元素大小那么多!


说这话之前要思量啊,哥。。。


呵呵, 你还没发现问题啊, 是本身就对指针加法没理解还是没看到代码?
比如说这段代码:

    else if(optionType == 2)
    {
        printf("请依次输入选项标号(请注意标号为数字):");            
         options = (int *) malloc(sizeof(int)*optionCount);                     
        for(int i=0; i<optionCount; ++i)
        {
            scanf("%d", (int *)options + sizeof(int)*i);
        }        
    }


里面的  (int *)options + sizeof(int)*i , 假设 options = 0, i = 4, 它的结果是多少?
是 0 + sizeof(int) * i = 0 + 4 * 4 = 16 ? 
错了, C 语言给你算成的是 0 + sizeof(int) * sizeof(int) * i = 64!
明白了没?
"指针加1不是增加一个字节,而是增加指向元素大小那么多"
如果你是怀疑这句话本身, 随便找本书或者自己写两行代码运行下就清楚了.

如果你还没发现这种方式造成了哪里越界, 把你访问的地址都打印出来, 把你申请的地址和大小也打印出来对比下吧!

热点排行