《C Primer Plus》 学习笔记系列之(五)
第14章 结构和其他数据形式
结构体
#include<stdio.h>
#define MAXTITL 41 //书名最大长度+1
#define MAXAUTL 31 //作者名的最大长度+1
struct book //结构体
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main()
{
struct book library;
printf("Please enter the book title.\n");
gets(library.title);
printf("Now enter the quthor.\n");
gets(library.author);
printf("Now enter the value.\n");
scanf("%f", &library.value);
printf("%s:\"%s\"($%.2f)", library.author, library.title, library.value);
printf("Done!\n");
return 0;
}
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()分配刚好满足字符串需求数量的空间。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
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 *); //用完释放内存
int main()
{
struct namect person;
getinfo(&person);
makeinfo(&person);
showinfo(&person);
cleanup(&person);
}
void getinfo(struct namect * pst)
{
char temp[81];
printf("Please enter your first name.\n");
gets(temp);
//分配用来存放名字的内存
pst->fname = (char *)malloc(strlen(temp) + 1);
//把名字复制到已分配的内存中
strcpy(pst->fname, temp);
printf("Please enter your last name.\n");
gets(temp);
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 contain %d letters.\n", pst->fname, pst->lname, pst->letters);
}
void cleanup(struct namect * pst)
{
free(pst->fname); //释放内存
free(pst->lname);
}
联合类型 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()的地址。
还没有评论,来说两句吧...