</pre><p><span style="font-size: 32px;">一、结构</span></p><p></p><pre name="code" class="plain">#include <stdio.h>
#define MAXTITL 41 // maximum length of title + 1
#define MAXAUTL 31 // maximum length of author's name + 1
struct book { // structure template: tag is book
char title[MAXTITL];
char author[MAXAUTL];
float value;
}; // end of structure template
int main(void)
{
struct book library; // declare library as a book variable
printf("Please enter the book title.\n");
gets(library.title); // access to the title portion
printf("Now enter the author.\n");
gets(library.author);
printf("Now enter the value.\n");
scanf("%f", &library.value);
printf("%s by %s: $%.2f\n",library.title,
library.author, library.value);
printf("%s: \"%s\" ($%.2f)\n", library.author,
library.title, library.value);
printf("Done.\n");
return 0;
}
1、声明结构
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
或者
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
} library
或者
struct {
char title[MAXTITL];
char author[MAXAUTL];
float value;
} library
2、初始化结构
struct book library={ "C Primer Plus ","Stephen Prata",60.0};
指定初始化项目
</pre><pre name="code" class="plain">struct book library={
.title="C Primer Plus ",
.author="Stephen Prata",
.value=60.0
};
</pre><p></p><pre>
3、访问结构成员
library.value
4、结构数组
#include <stdio.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index;
printf("Press [enter] at the start of a line to stop.\n");
printf("Please enter the book title.\n");
while (count < MAXBKS && gets(library[count].title) != NULL
&& library[count].title[0] != '\0')
{
printf("Now enter the author.\n");
gets(library[count].author);
printf("Now enter the value.\n");
scanf("%f", &library[count++].value);
while (getchar() != '\n')
continue;
if (count < MAXBKS)
printf("Enter the next title.\n");
}
if (count > 0)
{
printf("Here is the list of your books:\n");
for (index = 0; index < count; index++)
printf("%s by %s: $%.2f\n", library[index].title,
library[index].author, library[index].value);
}
else
printf("No books? Too bad.\n");
return 0;
}
5、指向结构的指针
#include <stdio.h>
#define LEN 20
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",
"personnal coach",
58112.00
}
,{{"Rodeny","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);
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;
}
-------------------------------------------------------------------------------------------------------
address #1:0028FE90;#2:0028FEE4
*pointer #1:0028FE90 #2:0028FEE4
him->income is $58112.00 ;(*him).income is ;$58112.00
him->favfood is tripe ;him->handle.last is Swillbelly
讨论:在结构中使用字符数组还是字符指针?
struct names {
char first[LEN];
char last[LEN];
};
可以改成这样吗?
struct pnames {
char * first;
char * last;
};
确实可以,但是会遇到麻烦。
struct names veep ={ "Ewen","Villard"} ;
struct pnames treas={ "Brad","Fallingjaw"} ;
对于veep 来说 字符串存储在LEN长度的数组里。
对于treas来说,字符串存到哪去了?
pnames 结构不会为字符串分配任何存储空间。只适合用于在另外的地方已经为字符串分配了空间。
如果需要一个结构来存储字符串,建议使用字符数组成员,或者用一个已经分配空的字符串的地址赋给字符指针。
6、结构、指针和malloc( )
struct namect {
char * first;
char * last;
int letters;
};
void getinfo(struct namect * );
void makeinfo(struct namect * );
void showinfo(const struct namect * );
void cleanup(struct namect * );
int main(void)
{
struct namect person;
getinfo(&person);
makeinfo(&person);
showinfo(&person);
cleanup(&person);
return 0;
}
void getinfo(struct namect * pst)
{
char temp [81];
printf("Please enter your first name.\n");
gets(temp);
pst->first = (char*)malloc(strlen(temp)+1);
strcpy(pst->first,temp);
printf("Please enter your last name.\n");
gets(temp);
pst->last = (char*)malloc(strlen(temp)+1);
strcpy(pst->last,temp);
}
void makeinfo(struct namect * pst)
{
pst->letters = strlen(pst->first)+strlen(pst->last);
}
void showinfo(const struct namect * pst)
{
printf("%s %s ,your name contains %d letters .\n",pst->first,pst->last,pst->letters);
}
void cleanup(struct namect * pst)
{
free(pst->first);
free(pst->last);
}
7、复合文字和结构(C99)
可以使用复合文字创建一个被用来作为函数参数或赋值给另一个结构的结构。语法是把类型名写在圆括号中,后面跟一个花括号括起来的初始化项目列表。
(struct book) {"The Idiot","pyodor Dos",6.99}
二、联合
当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。
1)联合体是一个结构;
2)它的所有成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合其中所有的成员;
由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。
下面举例说明:
如联合体
union U { char s[9]; int n; double d; };
从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,
即其大小必须满足两个条件:
1)大小足够容纳最宽的成员;
2)大小能被其包含的所有基本数据类型的大小所整除。
union U
{
char s[9];
int n;
double d;
};
int main(void)
{
union U text;
union U * textP;
printf("%d\n",sizeof(text));
printf("%#p\n",&text);
printf("%#p\n",&text.d);
printf("%#p\n",text.s);
printf("%#p\n",&text.n);
printf("%#p\n",textP);
printf("%#p\n",&textP->d);
printf("%#p\n",&textP->n);
printf("%#p\n",&textP->s);
text.d=25.0;
text.n = 12;
// text.s = "union";
// text.s[0] = 'u';
// text.s[1] = 'n';
// text.s[2] = 'i';
// text.s[3] = 'o';
// text.s[4] = 'n';
// text.s[5] = '\0';
printf("%d\n",text.d);
printf("%d\n",text.n);
// printf("%s\n",text.s);
return 0;
}<span style="color:#990000;">
</span>
-----------------------------------------------------
16
0X0028FF30
0X0028FF30
0X0028FF30
0X0028FF30
0X77201162
0X77201162
0X77201162
0X77201162
12
12
三、枚举类型
<span style="font-size:18px;">int main(void)
{
//默认起始为0,我这里设置为1。以后递增。可以为负。
enum dayOfWeek {Mon, Tue=0, Wed, Thu, Fri, Sat, Sun};
enum dayOfWeek dayNum;
int i;
dayNum = Fri;
printf("Mon is %d dayOfWeek\n ", Mon);
printf("Wed is %d dayOfWeek\n ", Wed);
printf("Fri is %d dayOfWeek\n ", dayNum);
i = 0;
i = dayNum + 1;
printf("i is %d \n ", i);
return 0;
}</span>
四、typeof简介
和#define相似,但是它们具有3个不同之处。
1)typeof给出的符号名称仅限于对类型,而不是对值。
2)typeof的解释由编译器,而不是预处理器执行。