struct point {
int x;
int y;
};
1.关键字struct引入结构声明。struct后面的名字是可选的,称为结构标记(这里为point).结构标记用于为结构命名,在定义之后,结构标记就代表花括号内的声明,可以用它作为该声明的简写形式。
结构体中的变量称为结构成员。
struct声明定义了一种数据类型。在标志结构成员表结束的右话括号之后可以跟一个变量表,这与其他基本类型的变量声明是相同的。如:
struct {...} x, y, z;
从语法上讲与int x, y, z; 类似。
注:如果结构声明的后面不带变量表,则不需要为它分配存储空间,它仅仅描述了一个结构模板。
2.
在表达式中,可以通过下列形式引用某个特定结构中的成员:
结构名.成员
其中的结构运算符“.”将结构名与成员名连接起来。
如:struct point pt
打印点pt的坐标:printf("%d, %d\n", pt.x, pt.y);
3.结构的合法操作:作为一个整体复制和赋值,通过&运算符取地址,访问其成员。结构之间不可以进行比较。
4.3种可能的方法传递结构:
(1)分别传递各个结构成员
(2)传递整个结构
(3)传递指向结构的指针
struct rect {
struct point pt1;
struct point pt2;
};
规范化一个矩形:
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
struct rect canonrect(struct rect r)
{
struct rect temp;
temp.pt1.x = min(r.pt1.x, r.pt2.x);
temp.pt1.y = min(r.pt1.y, r.pt2.y);
temp.pt1.x = max(r.pt1.y, r.pt2.y);
temp.pt1.x = max(r.pt1.y, r.pt2.y);
return temp;
}
如果传递给函数的结构很大,使用指针方式的效率通常比复制整个结构体的效率要高。结构体指针类似与普通变量指针。
struct point *pp;
pp指向一个point结构,*pp即为该结构体,而(*pp).x和(*pp).y则是结构成员。
由于结构指针的使用频度非常高,为了方便,C提供了一种简写方式:
假定p是一个指向结构的指针,可以用 p->结构成员 这种形式引用相应的结构成员。
对于下面的声明:
struct rect r, *rp = &r;
下面2个表达式是等价的:
r.pt1.x
rp->pt1.x
3.1 声明 struct x1 { ...}; 和 typedef struct { ...} x2;有什么不同?
第一种形式声明了一个 ``结构标签'';第二种声明了一个 ``类型定义''。 主要的区别是在后文中你需要用 ``struct x1'' 引用第一种,而用 ``x2'' 引用第二种。也就是说, 第二种声明更像一种抽象类新 --- 用户不必知道它是一个结构, 而在声明它的实例时也不需要使用 struct 关键字。
注:多重结构体嵌套的声明,初始化
#include <stdio.h>
#include <stdlib.h>
struct C
{
int x;
int y;
};
struct B
{
int B_num;
struct C *c;
};
struct A
{
int A_num;
struct B *b;
};
int main()
{
struct A STE_A;
STE_A.A_num = 1;
STE_A.b = (struct B*)malloc(STE_A.A_num * sizeof(struct B));
STE_A.b[0].B_num = 2;
STE_A.b[0].c = (struct C*)malloc(STE_A.b[0].B_num * sizeof(struct C));
STE_A.b[0].c[0].x = 100;
STE_A.b[0].c[0].y = 200;
STE_A.b[0].c[1].x = 300;
STE_A.b[0].c[1].y = 400;
printf("STE_A.A_num = %d\n", STE_A.A_num);
printf("STE_A.b[0].B_num = %d\n", STE_A.b[0].B_num);
printf("STE_A.b[0].c[0].x = %d\n", STE_A.b[0].c[0].x);
printf("STE_A.b[0].c[0].y = %d\n", STE_A.b[0].c[0].y);
printf("STE_A.b[0].c[1].x = %d\n", STE_A.b[0].c[1].x);
printf("STE_A.b[0].c[1].y = %d\n", STE_A.b[0].c[1].y);
return 0;
}
注:指针用法的一个例子
#include <stdio.h>
#include <stdlib.h>
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
struct Node
{
int Element;
PtrToNode Next;
};
int IsEmpty(Stack S)
{
return S->Next == NULL;
}
Stack CreateStack(void)
{
Stack S;
S = (struct Node *)malloc(sizeof(struct Node));
//In here we can use: S = malloc(sizeof(struct Node));
if (S == NULL)
printf("Out of space!!!\n");
S->Next = NULL;
return S;
}
int main()
{
CreateStack();
return 0;
}
注:栈的数组实现及从中看struct结构体的使用
#include <stdio.h>
#include <stdlib.h>
#define EmptyTOS -1
#define MinStackSize 5
struct StackRecord
{
int Capacity;
int TopOfStack;
int *Array;
};
typedef struct StackRecord *Stack;
int IsEmpty(Stack S)
{
return S->TopOfStack == EmptyTOS;
}
int IsFull(Stack S)
{
if (S->TopOfStack == S->Capacity - 1)
return 1;
else
return 0;
}
void MakeEmpty(Stack S)
{
S->TopOfStack = EmptyTOS;
}
Stack CreateStack(int MaxElements)
{
Stack S;
if (MaxElements < MinStackSize)
printf("Stack size is too small\n");
S = malloc(sizeof(struct StackRecord));
if (S == NULL)
printf("Out of space!!!\n");
S->Array = malloc(sizeof(int) * MaxElements);
if (S->Array == NULL)
printf("Out of space!!!\n");
S->Capacity = MaxElements;
MakeEmpty(S);
return S;
}
void DisposeStack(Stack S)
{
if (S != NULL)
{
free(S->Array);
free(S);
}
}
void Push(int x, Stack S)
{
if (IsFull(S))
printf("Full stack!\n");
else
S->Array[++S->TopOfStack] = x;
}
int Top(Stack S)
{
if (!IsEmpty(S))
return S->Array[S->TopOfStack];
printf("Empty stack!\n");
return 0;
}
void Pop(Stack S)
{
if (IsEmpty(S))
printf("Empty stack!\n");
else
S->TopOfStack--;
}
int main()
{
Stack s = CreateStack(10);
Push(1, s);
Push(2, s);
Push(3, s);
Push(4, s);
Push(5, s);
printf("Top = %d\n", Top(s));
Pop(s);
printf("Top = %d\n", Top(s));
Pop(s);
printf("Top = %d\n", Top(s));
Pop(s);
printf("Top = %d\n", Top(s));
Pop(s);
printf("Top = %d\n", Top(s));
Pop(s);
DisposeStack(s);
return 0;
}
注:队列的数组实现及应用
#include <stdio.h>
#include <stdlib.h>
struct QueueRecord;
typedef struct QueueRecord *Queue;
struct QueueRecord
{
int Capacity; /* 队列的大小 */
int Front; /* 队头 */
int Rear; /* 队尾 */
int Size; /* 当前队列的大小 */
int *Array; /* 存储队列中的元素 */
};
int IsEmpty(Queue Q)
{
return Q->Size == 0;
}
void MakeEmpty(Queue Q)
{
Q->Size = 0;
Q->Front = 1;
Q->Rear = 0;
}
int IsFull(Queue Q)
{
return Q->Size == Q->Capacity;
}
static int Succ(int Value, Queue Q)
{
if (++Value == Q->Capacity)
Value = 0;
return Value;
}
void Enqueue(int x, Queue Q)
{
if (IsFull(Q))
printf("Full queue!\n");
else
{
Q->Size++;
Q->Rear = Succ(Q->Rear, Q);
Q->Array[Q->Rear] = x;
}
}
int Dequeue(Queue Q)
{
if (IsEmpty(Q))
printf("Empty queue!\n");
else
{
Q->Size--;
int tmp = Q->Array[Q->Front];
Q->Front = Succ(Q->Front, Q);
return tmp;
}
}
int DeFront(Queue Q)
{
if (IsEmpty(Q))
printf("Empty queue!\n");
else
{
return Q->Array[Q->Front];
}
}
Queue CreateQueue(int MaxElements)
{
Queue Q;
Q = malloc(sizeof(struct QueueRecord));
if (Q == NULL)
printf("out of space!\n");
Q->Capacity = MaxElements;
Q->Front = 1;
Q->Rear = 0;
Q->Size = 0;
Q->Array = malloc(sizeof(int) * MaxElements);
return Q;
}
int main()
{
Queue q = CreateQueue(10);
if (IsEmpty(q))
printf("The queue is empty!\n");
Enqueue(1, q);
printf("Front is : %d\n", DeFront(q));
Enqueue(2, q);
printf("Front is : %d\n", DeFront(q));
Dequeue(q);
printf("Front is : %d\n", DeFront(q));
return 0;
}