《C Primer Plus》 学习笔记系列之(五)

阳光穿透心脏的1/2处 2022-08-10 20:59 223阅读 0赞

第14章 结构和其他数据形式

结构体

  1. #include<stdio.h>
  2. #define MAXTITL 41 //书名最大长度+1
  3. #define MAXAUTL 31 //作者名的最大长度+1
  4. struct book //结构体
  5. {
  6. char title[MAXTITL];
  7. char author[MAXAUTL];
  8. float value;
  9. };
  10. int main()
  11. {
  12. struct book library;
  13. printf("Please enter the book title.\n");
  14. gets(library.title);
  15. printf("Now enter the quthor.\n");
  16. gets(library.author);
  17. printf("Now enter the value.\n");
  18. scanf("%f", &library.value);
  19. printf("%s:\"%s\"($%.2f)", library.author, library.title, library.value);
  20. printf("Done!\n");
  21. return 0;
  22. }

struct book //结构体
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
该声明描述了一个由两个字符数组和一个float变量的组成的结构。它并没有创建一个实际的数据对象,而是描述了组成这类对象的元素。
结构设计告诉编译器如何表示数据,但是它没有让计算机为数据分配空间。
struct book library;
看到这条指令,编译器会创建一个变量library。编译器使用book模板为该变量分配空间:一个具有MAXTITL个元素的char数组,
一个具有MAXAUTL个元素的char数组和一个float变量。这些存储空间是以一个名字library被结合在一起的。
下面的声明:
struct book library;
可以简化成:
struct book //结构体
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
}library; //定义之后紧跟变量名

声明结构的过程和定义结构变量的过程可以被合并成一步,如下所示:
struct //无标记
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
}library;
如果要多次使用一个结构模板,就需要使用带有标记的形式。

声明结构数组:struct book library[40];

结构体指针: struct book * book_ptr;
library 是一个book类型的结构,book_ptr = &library;
library.value == (*book_ptr).value == book_ptr->value;

在结构中使用指针处理字符串的一个有意义的例子是使用malloc()分配内存,并用指针来存放地址。
这个方法的优点是可以请求malloc()分配刚好满足字符串需求数量的空间。

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. struct namect
  5. {
  6. char * fname;
  7. char * lname;
  8. int letters;
  9. };
  10. void getinfo(struct namect *); //分配内存
  11. void makeinfo(struct namect *);
  12. void showinfo(const struct namect *);
  13. void cleanup(struct namect *); //用完释放内存
  14. int main()
  15. {
  16. struct namect person;
  17. getinfo(&person);
  18. makeinfo(&person);
  19. showinfo(&person);
  20. cleanup(&person);
  21. }
  22. void getinfo(struct namect * pst)
  23. {
  24. char temp[81];
  25. printf("Please enter your first name.\n");
  26. gets(temp);
  27. //分配用来存放名字的内存
  28. pst->fname = (char *)malloc(strlen(temp) + 1);
  29. //把名字复制到已分配的内存中
  30. strcpy(pst->fname, temp);
  31. printf("Please enter your last name.\n");
  32. gets(temp);
  33. pst->lname = (char *)malloc(strlen(temp) + 1);
  34. strcpy(pst->lname, temp);
  35. }
  36. void makeinfo(struct namect * pst)
  37. {
  38. pst->letters = strlen(pst->fname) + strlen(pst->lname);
  39. }
  40. void showinfo(const struct namect * pst)
  41. {
  42. printf("%s %s, your name contain %d letters.\n", pst->fname, pst->lname, pst->letters);
  43. }
  44. void cleanup(struct namect * pst)
  45. {
  46. free(pst->fname); //释放内存
  47. free(pst->lname);
  48. }

联合类型 union:

union hold{
int digit;
double bigfl;
char letter;
};
因为联合只存储一个值。剩下的和结构体的命名规则类似。

枚举类型 enum:

enum spectrum{red, orange, yellow, green, blue, violet};
enum spectrum color;
其中的red和orange都是int类型的,
printf(“%d %d”, red, orange);
输出:
0 1
for (color = red; color <= violet; color++)
{
}

typedef :

type unsigned char BYTE;
BYTE 就可以代表 unsigned char 了,
BYTE x; //x是unsigned char 类型

typedef char * STRING; //将STRING 识别为一个char指针。
STRING name, sign; //意思是char * name, * sign;

type struct complex
{
float real;
float imag;
}COMPLEX;
也可以略掉标记:
typedef struct
{
float real;
float imag;
}COMPLEX;
这样就可以使用COMPLEX来表示复数:
COMPLEX com = {3.0, 4.5};
COMPLEX com1;
com1 = com;

奇特的声明:

int **ptr; //指向int的指针的指针
int * risks[10]; //具有10个元素的数组,每个元素是一个指向int的指针。 想成int *类型。
int (*rusks)[10]; //一个指针,指向具有10个元素的int数组。
数组的[]和表示一个函数的()具有同样的优先级,这个优先级高于间接运算符*的优先级。

函数和指针:

声明指向函数的指针,一个函数的指针可以作为另一个函数的参数,告诉第二个函数使用哪一个函数。
比如声明一个:
void ToUpper(char *); //char * 类型的参量
void (*pf)(char *); //pf是一个指向函数的指针
这就使得(*pf)是一个函数,用(*pf)来代替了函数名ToUpper。
pf = ToUpper; ToUpper是ToUpper()的地址。

发表评论

表情:
评论列表 (有 0 条评论,223人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C Primer Plus

    这次写这段代码,刚开始不是很顺利,主要是卡在了输入过滤上。后来和同学讨论之后,找到了解决办法。用scanf输入的类型不同返回值不同,从而决定是否继续输入。 while(sca