C primer plus第14章(结构和其他数据形式)

//结构体与指针
#include <stdio.h>
#define LEN 20
//#include <console.h> //mac下需要
struct names
{
    char first[LEN];
    char last[LEN];
};

struct guy
{
    struct names handle;
    char favfood[LEN];
    char job[LEN];
    float income;
};
int main(void)
{
    struct guy fellow[2] =
    {
        {   {"Ewen","Villard"},
            "grilled salmon",
            "personality coach",
            58112.00
        },
        {   {"Rodney","Swillbelly"},
            "tripe",
            "tabloid editor",
            232400.00
        }
    };
    struct guy * him;//这是一个指向结构的指针
    printf("address #1:%p #2:%p\n",&fellow[0],&fellow[1]);
    //结构与数组不同,需要用取地址符(&)取地址
    him = &fellow[0];//告诉该指针它要指向的地址
    printf("pointer #1: %p #2:%p\n",him,him+1);
    //用指针获取结构的值用->运算符
    //him->income等同于fellow[0].income 等同于(*him).income
    printf("him->income is $%.2f:(*him) .income is $%.2f\n",him->income,(*him).income);
    him++;//指向下一个结构
    printf("him->favfood is %s:him->handle.last is %s\n",him->favfood,him->handle.last);
    return 0;
    //如果him是指向名为barnery的结构的指针
    //barney.income == (*him).income == him->income
}
//如果要在结构内声明指针而不是数组(指针只保存地址,如果声明数组则保存的是实际的值)
struct names
{
    char *fname;
    char *lname;
    int letters;
};

void getinfo(struct namect *pst) {

    char temp[81];
    printf("Please enter your first name.\n");
    gets(temp);
    //分配用来存放值的内存(用完别忘记free)
    pst->fname = (char*)malloc(strlen(temp) + 1);
    //把名字复制到已分配的内存中
    strcpy(pst->fname,temp);
    printf("Please enter your last name.\n");
    gets(temp);
    //分配用来存放值的内存(用完别忘记free)
    pst->lname = (char*)malloc(strlen(temp) + 1);
    //把名字复制到已分配的内存中
    strcpy(pst->lname,temp);
}
复合文字结构体readfirst = (struct book) {"dadsa","dsasadsa",9.99}
//伸缩型数组成员
#include <stdio.h>
#include <stdlib.h>
struct flex
{
    int count;
    double average;
    double scores[];//伸缩型数组成员
};
void showFlex(const struct flex *p);
int main(void)
{
    struct flex * pf1,*pf2;
    int n = 5;
    int i;
    int tot = 0;
    //为结构和数组分配存储空间
    //为结构分配存储空间sizeof(struct flex)
    //为数组分配存储空间n * sizeof(double)
    pf1 = malloc(sizeof(struct flex) + n * sizeof(double));
    pf1->count = n;
    for(i=0; i<n; i++)
    {
        pf1->scores[i] = 20.0 - i;
        tot += pf1->scores[i];
    }
    pf1->average = tot / n;
    showFlex(pf1);
    n= 9;
    tot = 0;
    pf2 = malloc(sizeof(struct flex) + n * sizeof(double));
    pf2->count = n;
    for(i=0; i<n; i++)
    {
        pf2->scores[i] = 20.0 - i/2.0;
        tot += pf2->scores[i];
    }
    pf2->average = tot / n;
    showFlex(pf2);
    free(pf1);
    free(pf2);
    return 0;
}
void showFlex(const struct flex *p)
{
    int i;
    printf("Scores:");
    for(i=0; i<p->count; i++)
    {
        printf("%g ",p->scores[i]);
    }
    printf("\nAverage:%g\n",p->average);
}

将结构写入文件保存

#include <stdio.h>
#include <stdlib.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10 //图书最多的本书

//建立book模板
struct book
{
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};

int main(void)
{
    struct book library[MAXBKS];//结构数组
    int count = 0;
    int index,filecount;
    FILE *pbooks;
    int size = sizeof(struct book);
    //以二进制的追加模式打开文件
    if((pbooks = fopen("book.dat","a+b")) == NULL)
    {
        fputs("Can`t open book.dat file\n",stderr);
        exit(1);
    }
    //定位到文件开始处
    rewind(pbooks);

    //读取并输出文件中已经存在的数据
    while(count < MAXBKS && fread(&library[count],size,1,pbooks) == 1)
    {
        if(count == 0)
        {
            puts("Current contents of book.dat");
        }
        printf("%s by %s:$%.2f\n",library[count].title,library[count].author,library[count].value);
        count++;
    }

    filecount = count;
    //如果文件存储已满
    if(count == MAXBKS)
    {
        fputs("The book.dat file is full.",stderr);
        exit(2);
    }

    //如果文件还能存储
    puts("Please add new book titles.");
    puts("Press [enter] at the start of a line to stop.");
    //录入新的图书
    while(count <MAXBKS && gets(library[count].title) != NULL && library[count].title[0] != '\0')
    {
        puts("Now enter the author.");
        gets(library[count].author);
        puts("Now enter the value.");
        //下标递增
        scanf("%f",&library[count++].value);
        //清空输入行
        while(getchar() != '\n')
        {
            continue;
        }
        //如果未大于最大存储数量,提示输入下一本
        if(count< MAXBKS)
        {
            puts("Enter the next title");
        }
    }

    //写入文件
    if(count > 0)
    {
        puts("Here is the list of your books:");
        for(index = filecount; index < count; index++)
        {
            printf("%s by %s:$%.2f\n",library[index].title,library[index].author,library[index].value);
            //count-filecount 本次写入数量(本次写入后总数-写入前总数)
            fwrite(&library[filecount],size,count-filecount,pbooks);
        }
    }
    else
    {
        puts("No books? Too bad.\n");
    }
    puts("Bye.\n");
    fclose(pbooks);
    return 0;
}


函数指针

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

char showmenu(void);
void eatline(void);//读至行末
void show(void(*fp)(char *),char * str);
void ToUpper(char *);   //把字符串转换为大写
void ToLower(char *);   //把字符串转换为小写
void Transpose(char *);  //大小写专置
void Dummy(char *);     //不改变字符串

int main(void)
{
    char line[81];
    char copy[81];
    char choice;
    void(*pfun)(char *);//指向一个函数,该函数接受一个char*参数,并且没有返回值
    puts("Enter astring(empty line to quit):");
    while(gets(line) != NULL && line[0] != '\0')
    {
        while((choice = showmenu()) != 'n')
        {
            //用switch语句用来设置指针赋值不同的函数地址
            switch(choice)
            {
            case 'u':
                pfun = ToUpper;
                break;
            case 'l':
                pfun = ToLower;
                break;
            case 't':
                pfun = Transpose;
                break;
            case 'o':
                pfun = Dummy;
                break;
            }
            strcpy(copy,line);//为show()制作一份拷贝
            show(pfun,copy);//使用用户选择的函数
        }
        puts("Enter astring(empty line to quit):");

    }
    puts("Bye!");
    return 0;
}

char showmenu(void)
{
    char ans;
    puts("Enter menu choice:");
    puts("u)uppercase l)lowercase");
    puts("t)transposed case o)original case");
    puts("n)next string");
    ans = getchar();            //获取用户的响应
    ans = tolower(ans);         //转换为小写
    eatline();                  //删除行中剩余部分
    while(strchr("ulton",ans) == NULL)
    {
        puts("Please enter a u,l,t,o, or n:");
        ans = tolower(getchar());
        eatline();
    }
    return ans;
}

void eatline(void)
{
    while(getchar()!= '\n')
    {
        continue;
    }

}

void ToUpper(char * str)
{
    while(*str)
    {
        *str = toupper(*str);
        str++;
    }
}

void ToLower(char * str)
{
    while(*str)
    {
        *str = tolower(*str);
        str++;
    }
}

void Transpose(char * str)
{
    while(*str)
    {
        if(islower(*str))
        {
            *str = toupper(*str);
        }
        else if(isupper(*str))
        {
            *str = tolower(*str);
        }
        str++;
    }
}

void Dummy(char * str)
{
    //不改变字符串
}

void show(void(*fp)(char*),char * str)
{
    (*fp)(str);//把用户选择的函数作用于str
    puts(str);//显示结果
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值