首页 > 用户发贴区 > 编程问题提问区 > C程序中内存引用错误
2009
11-17

C程序中内存引用错误

找了半天,也没发现到底是哪条语句出了问题……而且程序中的display_report()函数也没有看明白到底是怎么实现的,原作者的意图是什么……该段代码可以通过编译连接,也生成了exe文件,可就是执行时总是出问题,(说明:我用的C-Free 4.0的IDE)请大牛指点批评。(源代码选自《21天学通C语言》一书,有少部分修改,中文注释是我自己加的)

源代码比较简单,贴于下面:

/*该程序实现用户信息记录、打印的功能*/

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

#define MAX 100
#define YES 1
#define NO 0

struct record          //定义用于记录用户信息的结构体
{
    char fname[15+1];  // first name
    char lname[20+1];  //last name
    char phone[9+1];   //记录电话号码
    long income;       //记录收入
    int month;         //以下三项纪录用户生日
    int day;
    int year;
};         //第一次编辑,这里都掉了一个分号,要了命了!

struct record list[MAX];  //声明一个结构体数组

int last_entry = 0;       //最后输入的个数,用于记录数组中共有几条记录

int main( void );    
void get_data( void );           //录入用户名字的函数
void display_report( void );     //打印记录,就是打印结构体数组的内容
int continue_function( void );   //一个用户的信息录入完毕,询问用户是否继续的函数
void clear_kb( void );           //用于清空输入缓冲区的函数

int main( void )
{
    int cont = YES;
    int ch;
   
    while( cont == YES )     //用cont控制是否进入该“死循环”,后面跳出时,把cont值赋值为NO
    {
        printf( “\n”);
        printf( “\n        MENU” );
        printf( “\n   =========\n” );
        printf( “\n1. Enter names” );
        printf( “\n2. Print report” );
        printf( “\n3. Quit”);
        printf( “\n\nEnter Your Selection ==>” );
       
       
        fflush( stdin );
       
        ch = getchar();    //这句第一次写成了:char = getchar(); ,也够受的!
       
        switch( ch )
        {
            case ’1′ :get_data();
                         break;
              case ’2′ :display_report();
                        break;
             case ’3′ :printf( “\n\nThank you for using this program !\n” );
                       cont = NO;   //cont值变为NO,while条件不满足,退出!
                       break;
            default :printf( “\n\nInvalid choice , Please select 1 to 3 !” );
                       break;
        }             
    }
    return 0;
}

void get_data( void )    //录入用户输入的信息
{
    int cont;
    for( cont = YES; last_entry < MAX && cont == YES; last_entry++ )
       //这个判断条件中的cont == YES是什么意思?有什么作用吗?
       //知道了:用来判断用户是否继续录入的控制变量!若没有,则for会一直循环下去,直到结构体数组变满。
       // 这个cont变量是continue_function()函数的返回值!
    {
        printf( “\n\nEnter information for Person %d .”, last_entry+1 );
       
        printf( “\n\nEnter first name: ” );
        fflush( stdin );
        gets( list[last_entry].fname );
        //scanf( “%s”, list[last_entry].fname );
       
        printf( “\nEnter last name: ” );
        fflush( stdin );
        gets( list[last_entry].lname );
       
        printf( ” \nEnter phone number in 123-4567 formate: ” );
        fflush( stdin );
        gets( list[last_entry].phone );
       
        printf( “\nEnter Yearly Income (whole dollars): ” );
        fflush( stdin );
        scanf( “%d”, &list[last_entry].income );
       
        printf( “\nEnter Birthday: ” );
        fflush( stdin );
       
        do
        {
            printf( “\n\tMonth (0 – 12): ” );
            scanf( “%d”, &list[last_entry].month );
        }while( list[last_entry].month < 0 || list[last_entry].month > 12 );
              //这样的while循环判断条件挺不错的:用不满足的条件做判断,
              //也就是说,只要用户输入的信息不符合,就会一直do下去… … 直到输入正确的信息
        do
        {
            printf( “\n\tDay (0 – 31): ” );
            scanf( “%d”, list[last_entry].day );
        }while( list[last_entry].day < 0 || list[last_entry].day > 31 );
       
        do
        {
            printf( “\n\tYear (1800 – 1997): ” );
            scanf( “%d”, &list[last_entry].year );
        }while( list[last_entry].year != 0 && (list[last_entry].year < 1800 || list[last_entry].year > 1997) );
             //此处的判断条件为什么还要加上list[last_entry].year != 0 呢?
        cont = continue_function();
    }
   
    if( last_entry == MAX )
    printf( “\n\nMaximum Number of Names has been entered ! \n” );
}

void display_report()
{
    long month_total = 0, grand_total = 0;
    int x,y;
   
    fprintf( stdout, “\n\n” );  //无作用,跳过一些行
    fprintf( stdout, “\n       REPORT” );  //这句和下一句都是为了美化输出而写的
    fprintf( stdout, “\n      ========” );
   
    for( x = 0; x <= 12; x++ )  //这个好像是靠月份来循环的… …
    {
        month_total = 0;
        for( y = 0; y < last_entry; y++ )  
        {
            if( list[y].month == x )
            {
                fprintf( stdout, “\n\t%s %s %s %ld”, list[y].fname,
                  list[y].lname, list[y].phone, list[y].income );
                  month_total += list[y].income;
            }
        }
       
        fprintf( stdout, “\nTotal for month %d is %ld”, x, month_total );
                grand_total += month_total;
    }
   
    fprintf( stdout, “\n\nReport totals: “);
    fprintf( stdout, “\nTotal Income is %ld”, grand_total );
    fprintf( stdout, “\nAverage Income is %ld”, grand_total/last_entry );
   
    fprintf( stdout, “\n\n* * * End of Report * * *” );
}

int continue_function( void )
{
    int ch;
   
    printf( “\n\nDo you wish to continue ?  (Y)es/(N)o: ” );
   
    fflush( stdin );
    ch = getchar();
   
    while( ch != ‘n’ && ch != ‘N’ && ch != ‘y’ && ch != ‘Y’ ) //如果输入不合法,就输出下列信息
    {   //|’N'|to Quit or|’y'|to Continue: “};
        printf( “\n%c is invalid! “, ch);
        printf( “\n\nPlease enter \’N\’to Quit or \’Y\’to Continue. ” );
       
        fflush( stdin );
        ch = getchar();
    }
   
    if( ch == ‘n’ || ch == ‘N’ )
    {
        return(NO);  //返回NO值,则continue_function()中的for循环就会因为条件不满足而退出。
    }
    else
    {
        return(YES); //返回YES值,调用函数的判断条件满足,就会进入下一个循环:继续读入用户信息
    }
}

void clear_kb( void )  //清空用户输入的多余信息
{
    char junk[80];
    gets( junk );
}

晚辈先谢过各位了……
   

       
   


C程序中内存引用错误》有 1 条评论

  1. C-Wolf 说:

    找了半天,也没发现到底是哪条语句出了问题……而且程序中的display_report()函数也没有看明白到底是怎么实现的,原作者的意图是什么……该段代码可以通过编译连接,也生成了exe文件,可就是执行时总是出问题,(说明:我用的C-Free 4.0的IDE)请大牛指点批评。(源代码选自《21天学通C语言》一书,有少部分修改,中文注释是我自己加的)

    源代码比较简单,贴于下面:

    /*该程序实现用户信息记录、打印的功能*/

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

    #define MAX 100
    #define YES 1
    #define NO 0

    struct record          //定义用于记录用户信息的结构体
    {
        char fname[15+1];  // first name
        char lname[20+1];  //last name
        char phone[9+1];   //记录电话号码
        long income;       //记录收入
        int month;         //以下三项纪录用户生日
        int day;
        int year;
    };         //第一次编辑,这里都掉了一个分号,要了命了!

    struct record list[MAX];  //声明一个结构体数组

    int last_entry = 0;       //最后输入的个数,用于记录数组中共有几条记录

    int main( void );    
    void get_data( void );           //录入用户名字的函数
    void display_report( void );     //打印记录,就是打印结构体数组的内容
    int continue_function( void );   //一个用户的信息录入完毕,询问用户是否继续的函数
    void clear_kb( void );           //用于清空输入缓冲区的函数

    int main( void )
    {
        int cont = YES;
        int ch;
       
        while( cont == YES )     //用cont控制是否进入该“死循环”,后面跳出时,把cont值赋值为NO
        {
            printf( “\n”);
            printf( “\n        MENU” );
            printf( “\n   =========\n” );
            printf( “\n1. Enter names” );
            printf( “\n2. Print report” );
            printf( “\n3. Quit”);
            printf( “\n\nEnter Your Selection ==>” );
           
           
            fflush( stdin );
           
            ch = getchar();    //这句第一次写成了:char = getchar(); ,也够受的!
           
            switch( ch )
            {
                case ’1′ :get_data();
                             break;
                  case ’2′ :display_report();
                            break;
                 case ’3′ :printf( “\n\nThank you for using this program !\n” );
                           cont = NO;   //cont值变为NO,while条件不满足,退出!
                           break;
                default :printf( “\n\nInvalid choice , Please select 1 to 3 !” );
                           break;
            }             
        }
        return 0;
    }

    void get_data( void )    //录入用户输入的信息
    {
        int cont;
        for( cont = YES; last_entry < MAX && cont == YES; last_entry++ )
           //这个判断条件中的cont == YES是什么意思?有什么作用吗?
           //知道了:用来判断用户是否继续录入的控制变量!若没有,则for会一直循环下去,直到结构体数组变满。
           // 这个cont变量是continue_function()函数的返回值!
        {
            printf( “\n\nEnter information for Person %d .”, last_entry+1 );
           
            printf( “\n\nEnter first name: ” );
            fflush( stdin );
            gets( list[last_entry].fname );
            //scanf( “%s”, list[last_entry].fname );
           
            printf( “\nEnter last name: ” );
            fflush( stdin );
            gets( list[last_entry].lname );
           
            printf( ” \nEnter phone number in 123-4567 formate: ” );
            fflush( stdin );
            gets( list[last_entry].phone );
           
            printf( “\nEnter Yearly Income (whole dollars): ” );
            fflush( stdin );
            scanf( “%d”, &list[last_entry].income );
           
            printf( “\nEnter Birthday: ” );
            fflush( stdin );
           
            do
            {
                printf( “\n\tMonth (0 – 12): ” );
                scanf( “%d”, &list[last_entry].month );
            }while( list[last_entry].month < 0 || list[last_entry].month > 12 );
                  //这样的while循环判断条件挺不错的:用不满足的条件做判断,
                  //也就是说,只要用户输入的信息不符合,就会一直do下去… … 直到输入正确的信息
            do
            {
                printf( “\n\tDay (0 – 31): ” );
                scanf( “%d”, list[last_entry].day );
            }while( list[last_entry].day < 0 || list[last_entry].day > 31 );
           
            do
            {
                printf( “\n\tYear (1800 – 1997): ” );
                scanf( “%d”, &list[last_entry].year );
            }while( list[last_entry].year != 0 && (list[last_entry].year < 1800 || list[last_entry].year > 1997) );
                 //此处的判断条件为什么还要加上list[last_entry].year != 0 呢?
            cont = continue_function();
        }
       
        if( last_entry == MAX )
        printf( “\n\nMaximum Number of Names has been entered ! \n” );
    }

    void display_report()
    {
        long month_total = 0, grand_total = 0;
        int x,y;
       
        fprintf( stdout, “\n\n” );  //无作用,跳过一些行
        fprintf( stdout, “\n       REPORT” );  //这句和下一句都是为了美化输出而写的
        fprintf( stdout, “\n      ========” );
       
        for( x = 0; x <= 12; x++ )  //这个好像是靠月份来循环的… …
        {
            month_total = 0;
            for( y = 0; y < last_entry; y++ )  
            {
                if( list[y].month == x )
                {
                    fprintf( stdout, “\n\t%s %s %s %ld”, list[y].fname,
                      list[y].lname, list[y].phone, list[y].income );
                      month_total += list[y].income;
                }
            }
           
            fprintf( stdout, “\nTotal for month %d is %ld”, x, month_total );
                    grand_total += month_total;
        }
       
        fprintf( stdout, “\n\nReport totals: “);
        fprintf( stdout, “\nTotal Income is %ld”, grand_total );
        fprintf( stdout, “\nAverage Income is %ld”, grand_total/last_entry );
       
        fprintf( stdout, “\n\n* * * End of Report * * *” );
    }

    int continue_function( void )
    {
        int ch;
       
        printf( “\n\nDo you wish to continue ?  (Y)es/(N)o: ” );
       
        fflush( stdin );
        ch = getchar();
       
        while( ch != ‘n’ && ch != ‘N’ && ch != ‘y’ && ch != ‘Y’ ) //如果输入不合法,就输出下列信息
        {   //|’N'|to Quit or|’y'|to Continue: “};
            printf( “\n%c is invalid! “, ch);
            printf( “\n\nPlease enter \’N\’to Quit or \’Y\’to Continue. ” );
           
            fflush( stdin );
            ch = getchar();
        }
       
        if( ch == ‘n’ || ch == ‘N’ )
        {
            return(NO);  //返回NO值,则continue_function()中的for循环就会因为条件不满足而退出。
        }
        else
        {
            return(YES); //返回YES值,调用函数的判断条件满足,就会进入下一个循环:继续读入用户信息
        }
    }

    void clear_kb( void )  //清空用户输入的多余信息
    {
        char junk[80];
        gets( junk );
    }

    晚辈先谢过各位了……
       

           
       

  2. delfeer 说:

     do
            {
                printf( “\n\tDay (0 – 31): ” );
                scanf( “%d”, list[last_entry].day );
            }while( list[last_entry].day < 0 || list[last_entry].day > 31 );
    没有仔细看,你查一下应该为:
     do
            {
                printf( “\n\tDay (0 – 31): ” );
                scanf( “%d”, &list[last_entry].day );
            }while( list[last_entry].day < 0 || list[last_entry].day > 31 );

留下一个回复