• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C语言学习10:结构体,结构体应用,联合用法,枚举,fopen函数使用,fseek,ftell的作 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

1,结构体以及两种用法

#include <stdio.h> 

struct s { 
    int a; 
    int b; 
    char s[6]; 
}; //结构体声明

int main(void) 
{ 
    struct s obj={ 
        .a=5, 
        .b=8, 
        .s="hello", 
    }; //结构体初始化

    printf("sizeof obj=%u\n",sizeof obj); //结果为16是两个int型占8个字节,最后一个数组要凑齐被4整除的边界只能是8,所以有16个字节。
    printf("&obj = %p,&obj.a=%p,&obj.b=%p\n" "&obj.s=%p,obj.s=%p\n",&obj,&obj.a,&obj.b,&obj.s,obj.s); 

    printf("-------------------------\n"); 
        //obj.s类型等同于 char * 
    //&obj.s类型等同于  char (*)[6] 
    printf("obj.s=%p,obj.s+1=%p\n",obj.s,obj.s+1); 
    printf("&obj.s=%p,&obj.s+1=%p\n",&obj.s,&obj.s+1); 
    printf("------------------------\n"); 
    //.是域(field)运算符/取成员运算符 
    printf("obj.a=%d,obj.b=%d,obj.s=%s\n",obj.a,obj.b,obj.s); 
    printf("==========================="); 
     
    //结构体取法 
    struct s *pobj = NULL; 
    pobj=&obj; 

    printf("sizeof pobj=%u\n",sizeof pobj); 
        printf("&pobj = %p,pobj = %p,&obj=%p\n",&pobj,pobj,&pobj); 
    printf("&pobj = %p,&pobj->a=%p,&pobj->b=%p\n" "&pobj->s=%p,pobj->s=%p\n",&pobj,&pobj->a,&pobj->b,&pobj->s,pobj->s); 

    printf("---------------------------------\n"); 
    printf("pobj->s=%p,pobj->s+1=%p\n",pobj->s,pobj->s+1); 
    printf("&pobj->s=%p,&pobj->s+1=%p\n",&pobj->s,&pobj->s+1); 
    printf("------------------------\n"); 
    //->是域运算符/取成员运算符 
    printf("pobj->a=%d,pobj->b=%d,pobj->s=%s\n",pobj->a,pobj->b,pobj->s); 

    return 0; 
}

结果:

will@will-laptop:~/ex/9$ ./a.out 
sizeof obj=16 
&obj = 0xbeb79174,&obj.a=0xbeb79174,&obj.b=0xbeb79178 
&obj.s=0xbeb7917c,obj.s=0xbeb7917c 
------------------------- 
obj.s=0xbeb7917c,obj.s+1=0xbeb7917d 
&obj.s=0xbeb7917c,&obj.s+1=0xbeb79182 
------------------------ 
obj.a=5,obj.b=8,obj.s=hello 
===========================sizeof pobj=4 
&pobj = 0xbeb79170,pobj = 0xbeb79174,&obj=0xbeb79170 
&pobj = 0xbeb79170,&pobj->a=0xbeb79174,&pobj->b=0xbeb79178 
&pobj->s=0xbeb7917c,pobj->s=0xbeb7917c 
--------------------------------- 
pobj->s=0xbeb7917c,pobj->s+1=0xbeb7917d 
&pobj->s=0xbeb7917c,&pobj->s+1=0xbeb79182 
------------------------ 
pobj->a=5,pobj->b=8,pobj->s=hello

2,结构体应用

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

struct s { 
    int a; 
    int b; 
    char s[6]; 
}; 

int main(void) 
{ 
    struct s obj={ 
        .a=6, 
        .b=8, 
        .s="hello", 
    }; 
    printf("obj.a=%d,obj.b=%d,obj.s=%s\n",obj.a,obj.b,obj.s); 
    printf("obj.a=%p,obj.b=%p,obj.s=%p\n",&obj.a,&obj.b,&obj.s); 
    printf("------------------------\n"); 

    struct s obj_copy; 
    //同类型结构体对象之间可以直接复制 
    obj_copy = obj; 
    printf("obj_copy.a=%d,obj_copy.b=%d,obj_copy.s=%s\n",obj.a,obj.b,obj.s); 
    printf("obj_copy.a=%p,obj_copy.b=%p,obj_copy.s=%p\n",&obj.a,&obj.b,&obj.s); 
    printf("------------------------\n"); 
    struct s *pobj=NULL; 
    pobj = malloc(sizeof(struct s)); 
    if(NULL==pobj) 
        return 1; 
        //结果体对象之间复制是浅拷贝 
//    pobj=&obj;这个是取地址,没有使用开辟的空间 
           *pobj = obj; 
    printf("pobj->a=%d,pobj->b=%d,pobj->s=%s\n",pobj->a,pobj->b,pobj->s); 
    printf("pobj->a=%p,pobj->b=%p,pobj->s=%p\n",&pobj->a,&pobj->b,&pobj->s); 
    free(pobj); 
    return 0; 
}

结果:

will@will-laptop:~/ex/9$ ./a.out 
obj.a=6,obj.b=8,obj.s=hello 
obj.a=0xbe869164,obj.b=0xbe869168,obj.s=0xbe86916c 
------------------------ 
obj_copy.a=6,obj_copy.b=8,obj_copy.s=hello 
obj_copy.a=0xbe869164,obj_copy.b=0xbe869168,obj_copy.s=0xbe86916c 
------------------------ 
pobj->a=6,pobj->b=8,pobj->s=hello 
pobj->a=0x7ee008,pobj->b=0x7ee00c,pobj->s=0x7ee010 

3,联合用法

#include <stdio.h> 

union u{ 
    int a; 
    char ch; 
    double d; 
}; 

int main(void) 
{ 
       union u uobj; 
       union u *pu=NULL; 

       pu=&uobj; 
       printf("sizeof uobj=%u\n",sizeof uobj); 
       //选取最大的大小,也就是双精度的八位
       uobj.a = 3; 
       printf("uobj.a=%d\n",uobj.a); 
       printf("uobj.d=%lf\n",uobj.d); //未初始化直接变成0
       printf("---------------\n"); 

       printf("&uobj.a=%p,&uobj.ch=%p\n""&uobj.d=%p,&uobj=%p\n",&uobj.a,&uobj.ch,&uobj.d,&uobj);

//这个说明位置没有根本变化,只能拿一个出来用, uobj.d=3.14; printf("uobj.d=%lf\n",uobj.d); printf("uobj.a=%d\n",uobj.a); //越界了a的值不对了。如果要使用a的值就需要在打印完后再自行赋值 printf("---------------\n"); uobj.ch='A'; printf("uobj.ch=%c\n",uobj.ch); printf("&uobj.a=%p,&uobj.ch=%p\n""&uobj.d=%p,&uobj=%p\n",&uobj.a,&uobj.ch,&uobj.d,&uobj); //结果表明每一调出的元素都是相同的地址,联合是提供了不同的元素 printf("---------------\n"); printf("&pu->a=%p,&pu->ch=%p\n""&pu->d=%p,pu=%p\n",&pu->a,&pu->ch,&pu->d,pu); //pu本身是存储地址的指针而已,所以不用取地址符 return 0; }

结果:

will@will-laptop:~/ex/9$ ./a.out 
sizeof uobj=8 
uobj.a=3 
uobj.d=0.000000 
--------------- 
&uobj.a=0xbe8d1188,&uobj.ch=0xbe8d1188 
&uobj.d=0xbe8d1188,&uobj=0xbe8d1188 
uobj.d=3.140000 
uobj.a=1374389535 
--------------- 
uobj.ch=A 
&uobj.a=0xbe8d1188,&uobj.ch=0xbe8d1188 
&uobj.d=0xbe8d1188,&uobj=0xbe8d1188 
--------------- 
&pu->a=0xbe8d1188,&pu->ch=0xbe8d1188 
&pu->d=0xbe8d1188,pu=0xbe8d1188 

4,枚举

#include <stdio.h> 
//枚举就是将变量的值一一列举出来, 
//变量的值只限于列举出来的值的范围内 
enum txt_attr { 
    color_start,//0 
    black,//1 
    white, 
    red, 
    yellow, 
    blue, 
    green, 
    orange, 
    color_end =32, 

    attr_start, 
    italic, 
    bold, 
    attr_end 
}; 

int main(void) 
{ 
    enum txt_attr txt; 

    txt = color_start; 
    printf("color_start = %d\n",txt); 
    txt=black; 
    printf("black       = %d\n",txt); 
    txt=orange; 
    printf("orange      = %d\n",txt); 
        txt=color_end; 
    printf("color_end   = %d\n",txt); 

    printf("---------------------------\n"); 

    txt=attr_start; 
    printf("attr_start  = %d\n",txt);//枚举就是排序有代号 
    printf("attr_start  = %d\n",attr_start); 

    txt=italic; 
    printf("italic      =%d\n",txt);//会自动加1,如果没有定义的话 

    return 0; 
}

结果:

will@will-laptop:~/ex/9$ ./a.out 
color_start = 0 
black       = 1 
orange      = 7 
color_end   = 32 
--------------------------- 
attr_start  = 33 
attr_start  = 33 
italic      =34 

5,fopen函数使用

#include <stdio.h> 
#include <errno.h> 

int main(void) 
{ 
    FILE *fp=NULL; 
    size_t ret=0; 

    fp=fopen("1.txt","w+");//打开文件,因为有w+没有就创建 
    if(NULL==fp) 
    { 
        //perror:根据errno解释错误原因并输出到stderr 
        //perror("fopen failed"); 

        //strerror:根据errno返回错误原因的字符串描述 
        fprintf(stderr,"fopen failed,%s\n",strerror(errno)); 
//错误标识语句
goto err0; } ret=fwrite("china unix",1,10,fp); if(ret!=10) { fprintf(stderr,"fwrite failed,%s\n",strerror(errno)); goto err1; } printf("------file writed,now read file-------\n"); rewind(fp); //文件内部位置指针指向开头 char s[32]={0}; ret=fread(s,1,10,fp); if(ret!=10) { perror("fread failed");//这个是固定用的 goto err1; } printf("now readed.s = %s\n",s); fclose(fp); return 0; err1: fclose(fp); err0: return 1; }

结果:

will@will-laptop:~/ex/9$ sudo ./a.out
[sudo] password for will: 
------file writed,now read file------- 
now readed.s = china unix 

6,fseek,ftell的作用和文件结束符EOF

#include <stdio.h>

int main(void)
{
    FILE *fp = NULL;
    size_t ret;
    int pos;

    fp = fopen("files/2.txt", "w+");
    if (NULL == fp)
    {
        perror("fopen failed");    
        goto err0;
    }

    pos = ftell(fp);//获得相对于文件首的偏移字数
    printf("file opened, pos = %d\n", pos);

    ret = fwrite("china", 1, 5, fp);
    if (5 != ret)
    {
        perror("fwrite failed");    
        goto err1;
    }
    printf("------'china' writed, pos = %d\n", ftell(fp));

    fseek(fp, 6, SEEK_CUR);//定位到文件头六个字节后
    pos = ftell(fp);
    printf("------fseek 6 bytes. pos = %d\n", pos);

    ret = fwrite(" unix", 1, 5, fp);
    if (5 != ret)
    {
        perror("fwrite failed");    
        goto err1;
    }
    printf("------' unix' writed, pos = %d\n", ftell(fp));

    rewind(fp);

    printf("read file and print now:\n");
    int ch;
    printf("EOF == %d\n", EOF);//文件结束符的值是-1
    while ((ch = fgetc(fp)) != EOF)//循环输出文件内容
        putchar(ch);
    putchar('\n');

    fclose(fp);

    return 0;
err1:
    fclose(fp);
err0:
    return 1;
}

结果:

file opened, pos = 0
------'china' writed, pos = 5
------fseek 6 bytes. pos = 11
------' unix' writed, pos = 16
read file and print now:
EOF == -1
china unix

7,数组和文件交换数据

#include <stdio.h> 

void rand_a(int *p,int len) 
{ 
    int i; 
    for(i=0;i<len;i++) 
        p[i]=rand()%100; 
} 

void print_a(int *p,int len) 
{ 
    int i; 
    for(i=0;i<len;i++) 
    { 
        printf("%d  ",p[i]); 
    } 
    putchar('\n'); 
} 

int main(void) 
{ 
    FILE *fp=NULL; 
    int a[10]={0}; 
    int b[10]={0}; 

    fp=fopen("3.int","w+"); 
    if(NULL==fp) 
    { 
        perror("fopen failed"); 
        goto err0; 
    } 

    rand_a(a,10); 
    printf("a:\n"); 
    print_a(a,10); 

    fwrite(a,sizeof(int),10,fp); 
    fclose(fp); 

    printf("--------------------\n"); 
    fp=fopen("3.int","r"); 
    if(NULL==fp) 
    { 
               perror("fopen failed"); 
           goto err0; 
    } 
     
    fread (b,sizeof(int),10,fp); 
    printf("b:\n"); 
    print_a(b,10); 

    fclose(fp); 

    return 0; 
err0: 
    return 1; 
}

结果:

will@will-laptop:~/ex/9$  ./a.out 
a: 
83  86  77  15  93  35  86  92  49  21  
-------------------- 
b: 
83  86  77  15  93  35  86  92  49  21  

8,个人信息管理

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

typedef struct _basic{ 
    int id; 
    char sex; 
    char name[32]; 
}basic_t; 

typedef struct _contact { 
    char qq[16]; 
    char email[]; 
}contact_t; 

typedef struct _person{ 
        struct _basic binfo; 
        contact_t *pcont; 
}person_t; 

int add_person(person_t **p,int *cnt) 
{ 
        p[*cnt]=malloc(sizeof(person_t)); 
    if(NULL==p[*cnt]) 
        goto err0; 
    p[*cnt]->pcont =malloc(sizeof(contact_t)); 
    if(NULL==p[*cnt]->pcont) 
        goto err1; 
    p[*cnt]->binfo.id=rand()%100; 
    p[*cnt]->binfo.sex ="MF"[rand()%2]; 
    printf("\tinput name:"); 
    gets(p[*cnt]->binfo.name); 

    printf("\tinput qq:"); 
    gets(p[*cnt]->pcont->qq); 
    printf("\tinput email:"); 
    gets(p[*cnt]->pcont->email); 

    *cnt +=1; 

    return 0; 
err1: 
    free(p[*cnt]); 
    p[*cnt]=NULL; 
err0: 
    return -1; 
} 

void print_person(person_t **p,int cnt) 
{ 
    int i; 
    for(i=0;i<cnt;i++) 
    { 
        printf("\t---第%d人信息:---\n",i+1); 
        printf("\tid:%d sex:%c name:%s\n",p[i]->binfo.id,p[i]->binfo.sex,p[i]->binfo.name); 
        printf("\tqq:%s email:%s\n",p[i]->pcont->qq,p[i]->pcont->email); 
    } 

     
} 

int save_person(person_t **p ,int cnt) 
{ 
    FILE *fp = NULL; 
    size_t ret; 
    int i; 
    if(NULL==(fp=fopen("person.db","w"))) 
    { 
        perror("fopen"); 
        goto err0; 
    } 
    if(1!=(ret=fwrite(&cnt,sizeof(int),1,fp))) 
        goto err1; 
    for(i=0;i<cnt;i++) 
    { 
        if(1!=fwrite(p[i],sizeof(person_t),1,fp)) 
            goto err1; 
        if(1!=fwrite(p[i]->pcont,sizeof(contact_t),1,fp)) 
            goto err1; 
    } 
    fclose(fp); 

    return 0; 
err1: 
    fclose(fp); 
err0: 
    return -1; 
} 

int load_person(person_t **p,int *cnt) 
{ 
    FILE *fp=NULL; 
    int i,j,count; 
    for(i=0;i<*cnt;i++) 
    { 
        free(p[i]->pcont); 
        free(p[i]); 
    } 

    if(NULL==(fp=fopen("person.db","r"))) 
        perror("fopen"); 
        goto err0; 
    if(1!=fread(&count,sizeof(int),1,fp)) 
        goto err1; 
    for(i=0;i<count;i++) 
    { 
        p[i]=malloc(sizeof(person_t)); 
        if(NULL==p[i]) 
            goto err2; 
        if(1!=fread(p[i],sizeof(person_t),1,fp)) 
            goto err2; 

        p[i]->pcont=malloc(sizeof(contact_t)); 
        if(NULL==p[i]) 
            goto err3; 
        if(1!=fread(p[i]->pcont,sizeof(contact_t),1,fp)) 
            goto err3; 

    } 
    *cnt=count; 
    fclose(fp); 

    return 0; 
err3: 
    free(p[i]); 
err2: 
    for(j=0;j<i;j++) 
    { 
        free(p[i]->pcont); 
        free(p[j]); 
        p[j]=NULL; 
    } 
err1: 
    fclose(fp); 
err0: 
        return -1; 

} 

int main(void) 
{ 
    person_t *pers[10]={NULL}; 
    printf("\t====>欢迎光临个人信息管理系统<====\n"); 

    int quit =0,ret,op; 
    int i,count=0; 
    while(!quit) 
    { 
retry: 
        printf("\t===>1.输入个人信息\n"); 
        printf("\t===>2.遍历个人信息\n"); 
        printf("\t===>3.存储个人信息\n"); 
        printf("\t===>4.读取个人信息\n"); 
        printf("\t===>5.退出\n"); 
        printf("\t===>请选择【1-5】"); 

        ret=scanf("%d",&op); 
        while(getchar()!='\n') 
            ; 
        if(ret==0) 
        { 
            printf("\t输入错误\n"); 
        } 
        switch (op) 
        { 
            case 1: 
                if(count >= 10) 
                { 
                    printf("\t只能存放10个个人信息!\n"); 
                    break; 
                } 
                if(0==add_person(pers,&count)) 
                    printf("\t 添加成功!\n"); 
                else 
                    printf("添加失败\n"); 
                case 2: 
                print_person(pers,count); 
                break; 
            case 3: 
                 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C语言输入语句scanf与fgetslinux下发布时间:2022-07-14
下一篇:
C#读写文件:十进制转十六进制发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap