【C语言】学习笔记9——结构struct(2)

简介: 1.如果使用 malloc() 分配内存并使用指针存储该地址,那么在结构中使用指针处理字符串就会显得比较合理。 #include #include // 提供strcpy()、strlen() 的原型 #include // 提供malloc()、free() 的原型...

1.如果使用 malloc() 分配内存并使用指针存储该地址,那么在结构中使用指针处理字符串就会显得比较合理。

#include <stdio.h>
#include <string.h>     // 提供strcpy()、strlen() 的原型
#include <stdlib.h>     // 提供malloc()、free() 的原型
#define SLEN 81

struct namect {
    char * fname;
    char * lname;
    int letters;
}; 

void getinfo(struct namect *);
void makeinfo(struct namect *);
void showinfo(const struct namect *);
void cleanup(struct namect *);
char * s_gets(char *, int );

int main()
{
    struct namect person;
    getinfo(&person);
    makeinfo(&person);
    showinfo(&person);
    cleanup(&person);
    return 0;
}

void getinfo(struct namect * pst)
{
    char temp[SLEN];
    printf("Please enter your first name:\n");
    s_gets(temp, SLEN);
    
    //分配内存以存储first name
    pst->fname = (char *) malloc(strlen(temp) + 1);
    //把first name 拷贝到分配的动态内存中 
    strcpy(pst->fname, temp);
    
    printf("Please enter your last name:\n");
    s_gets(temp, SLEN);
    pst->lname = (char *) malloc(strlen(temp) + 1);
    strcpy(pst->lname, temp);
}

void makeinfo(struct namect * pst)
{
    pst->letters = strlen(pst->fname) + strlen(pst->lname);
}

void showinfo(const struct namect *pst){
    printf("%s %s, your name contains %d letters.\n", pst->fname, pst->lname, pst->letters);
}


void cleanup(struct namect * pst)
{
    free(pst->fname);
    free(pst->lname);
}


char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');    //查找换行符
        if(find)               //如果地址不是null 
            *find = '\0';      //在此放置一个空字符 
        else
            while (getchar() != '\n')
                continue;
    }
    return ret_val; 
        
}

/*
output:
Please enter your first name:
James
Please enter your last name:
Harden
James Harden, your name contains 11 letters.
*/

2.复合字面量和结构:C99 的复合类型字面量特性可用于结构和数组。如果只需要一个临时结构值,符合字面量很好用。 可以把复合字面量创建一个数组作为函数的参数,或赋值给另一个结构。

下面是struct book 类型的复合字面量

#define MAXTITL 41
#define MAXAUTL 31

struct book{
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
}; 

(struct book) {"Crime and Punishment", "Fyodor Dostoyevsky", 11.25};         /* 使用复合字面量给赋值*/
#include <stdio.h>
#define MAXTITL 41
#define MAXAUTL 31

struct book{
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
}; 

int main()
{
    struct book readfirst;
    int score;
    
    printf("Enter test score: ");
    scanf("%d", &score);
    
    if(score >= 84)
        readfirst = (struct book) {       /* 使用复合字面量给赋值*/
            "Crime and Punishment",
            "Fyodor Dostoyevsky",
            11.25
        };
    else
        readfirst = (struct book) {
            "Mr.Bouncy's Nice Hat",
            "Fred Winsome",
            5.99
        };
    
    printf("Your assigned reading:\n");
    printf("%s by %s: $%.2f\n", readfirst.title, readfirst.author, readfirst.value);
    return 0;
}

/*
output:
Enter test score: 100
Your assigned reading:
Crime and Punishment by Fyodor Dostoyevsky: $11.25
*/ 

3. 伸缩型数据成员

  声明一个伸缩型数组成员必须遵守如下规则:

  a. 伸缩型数组成员必须是结构的最后一个成员;

  b. 结构中必须至少有一个成员;

  c. 伸缩数组的声明类似于普通数组,只是他的方括号中是空的。

struct flex
{
    int count;
    double average;
    double scores[];
};

  声明一个struct flex类型的结构变量时, 不能用scores做任何事,因为没有给这个数组预留存储空间。 这个用法的意图并不是让你声明struct flex 类型的变量, 而是希望你声明一个指向struct flex类型的指针,然后用malloc()来分配足够的空间,以存储struct flex类型结构的常规内容和伸缩型数组成员所需的额外空间。例如

struct flex * pf;   //声明一个指向 struct flex的指针
pf = malloc(sizeof(struct flex) + 5 * sizeof(double)); //请求为一个结构和一个数组分配存储空间

  然后你就有足够的存储空间去存储count, average 和 5个double类型的数组。用指针访问这些成员

pf->count = 5;            //设置count成员
pf->scores[2] = 18.5; //访问数组成员的一个元素

   但是, 带伸缩型数组成员的结构确实有一些特殊的处理要求

    a. 不能用结构进行赋值或拷贝   

struct flex *pf1, * pf2;
...
*pf2 = *pf1 //不要这样做,这样做只能拷贝伸缩型数组成员以外的其它成员。应使用memcpy()函数

    b. 不要按值方式把这种结构传递给结构

    c. 不要使用带伸缩型数组成员的结构作为数组成员或另一种结构的成员。

 

相关文章
|
16天前
|
C语言
C语言之分支结构
C语言之分支结构
23 0
|
1月前
|
C语言
C语言结构体内存对齐
C语言结构体内存对齐
|
2月前
|
Serverless C语言
C语言程序通常具有以下基本结构
C语言程序通常具有以下基本结构
11 0
|
2月前
|
C语言
C语言选择结构
C语言选择结构
17 0
|
2月前
|
存储 C语言
C语言顺序结构:基础与实践
C语言,作为一种广泛使用的编程语言,其程序结构可以分为三种基本类型:顺序结构、选择结构和循环结构。在这篇文章中,我们将重点讨论顺序结构的概念、特点以及如何在C语言中实现顺序结构的程序设计。
43 1
|
2月前
|
C语言
C语言选择结构
C语言选择结构
17 0
|
1月前
|
存储 编译器 Linux
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参
|
2月前
|
C语言
C语言最基本程序控制结构
C语言最基本程序控制结构
16 0
|
12天前
|
C语言
【精通C语言】:分支结构if语句的灵活运用
【精通C语言】:分支结构if语句的灵活运用
24 1
|
17天前
|
编译器 Linux C语言
C语言:结构体(自定义类型)知识点(包括结构体内存对齐的热门知识点)
C语言:结构体(自定义类型)知识点(包括结构体内存对齐的热门知识点)