Advanced Data Type
DataType
struct
record in pascal
program PrintBirthday;
type
birthday = record
year : integer;
month : integer;
day : integer;
end;
var
b : birthday;
begin
b := (year: 2000; month: 1; day: 1); // 创建并初始化生日记录
// 打印生日
writeln('Birthday: ', b.day, '/', b.month, '/', b.year);
end.
struct in C
//* book.c -- one-book inventory */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#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");
s_gets(library.title, MAXTITL); /* access to the title portion */
printf("Now enter the author.\n");
s_gets(library.author, MAXAUTL);
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;
}
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'); // look for newline
if (find) // if the address is not NULL,
*find = '\0'; // place a null character there
else
while (getchar() != '\n')
continue; // dispose of rest of line
}
return ret_val;
}
(base) kimshan@MacBook-Pro output % ./"book"
Please enter the book title.
Hello
Now enter the author.
Charles
Now enter the value.
10
Hello by Charles: $10.00
Charles: "Hello" ($10.00)
Done.struct 基础
声明
// 1
struct book { /* structure template: tag is book */
char title[MAXTITL];
char author[MAXAUTL];
float value;
}; /* end of structure template */
struct book library, *p_lib;
// 2 简化
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
} library, *p_lib;
// 3. 数组
struct book library[MAXBOOKS];
// 4. 嵌套
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
struct book[MAXRELATE] res;
} library[MAXBOOKS];
// 5 typedef
typedef struct BiTNode
{
int data;
struct BiTNode *lchild;
struct BiTNode *rchild;
//struct BiTNode *parent; // 变成了 三叉链表
}BiTNode,*BiTree;初始化
// 1. 按顺序
struct book library =
{
"The Pious Pirate and te Devious Damsel",
"Rennee Vivotte",
1.95
};
// 2. 按成员
struct book gift =
{
.value = 25.99;
.author = "Me";
.title = "You";
}访问
scanf("%f", &library.value);
s_gets(library.author, MAXAUTL);
scanf("%f", &p_lib->value);
s_gets(p_lib->author, MAXAUTL);struct + malloc
struct 中声明字符串然后 scanf 进来会导致错误(可能把字符串保存在任意位置)
#include <stdio.h>
#define LEN 20
struct names {
char first[LEN];
char last[LEN];
};
int main() {
struct names veep = {"Talia", "Summers"};
struct pnames treas = {"Brad", "Fallingjaw"};
printf("%s and %s\n", veep.first, treas.first);
struct names accountant;
struct names attorney;
printf("Enter the last name of your accountant: ");
scanf("%s", accountant.last);
printf("Enter the last name of your attorney: ");
scanf("%s", attorney.last); /* 这里有一个潜在的危险 */
return 0;
}现在更好的办法是,struct 里边不要字符串,而是改成指针,每次去 malloc
// names3.c -- use pointers and malloc()
#include <stdio.h>
#include <string.h> // for strcpy(), strlen()
#include <stdlib.h> // for malloc(), free()
#define SLEN 81
struct namect {
char * fname; // using pointers
char * lname;
int letters;
};
void getinfo(struct namect *); // allocates memory
void makeinfo(struct namect *);
void showinfo(const struct namect *);
void cleanup(struct namect *); // free memory when done
char * s_gets(char * st, int n);
int main(void)
{
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);
// allocate memory to hold name
pst->fname = (char *) malloc(strlen(temp) + 1);
// copy name to allocated memory
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'); // look for newline
if (find) // if the address is not NULL,
*find = '\0'; // place a null character there
else
while (getchar() != '\n')
continue; // dispose of rest of line
}
return ret_val;
}
struct 复合字面量(C99)
/* complit.c -- compound literals */
#include <stdio.h>
#define MAXTITL 41
#define MAXAUTL 31
struct book { // structure template: tag is book
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
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;
}伸缩型成员变量(C99)
结构体里边的数组不写 MAX,只写 方括号,这样后边的 malloc 就要去计算大小了
// flexmemb.c -- flexible array member (C99 feature)
#include <stdio.h>
#include <stdlib.h>
struct flex
{
size_t count;
double average;
double scores[]; // flexible array member
};
void showFlex(const struct flex * p);
int main(void)
{
struct flex * pf1, *pf2;
int n = 5;
int i;
int tot = 0;
// allocate space for structure plus array
pf1 = malloc(sizeof(struct flex) + n * sizeof(double));
pf1->count = n;
for (i = 0; i < n; i++)
{
pf1->scores[i] = 20.0 - i;
tot += pf1->scores[i];
}
pf1->average = tot / n;
showFlex(pf1);
n = 9;
tot = 0;
pf2 = malloc(sizeof(struct flex) + n * sizeof(double));
pf2->count = n;
for (i = 0; i < n; i++)
{
pf2->scores[i] = 20.0 - i/2.0;
tot += pf2->scores[i];
}
pf2->average = tot / n;
showFlex(pf2);
free(pf1);
free(pf2);
return 0;
}
void showFlex(const struct flex * p)
{
int i;
printf("Scores : ");
for (i = 0; i < p->count; i++)
printf("%g ", p->scores[i]);
printf("\nAverage: %g\n", p->average);
}
匿名结构(C11)
struct person
{
int id;
struct {char first[20]; char last[20];}; // 匿名结构
};
// 初始化
struct person ted = {8483, {"ted", "grass"}};结构体保存在文件中
#define MAXTITL 40
#define MAXAUTL 40
struct book {
char title[MAXTITL];
char author[ MAXAUTL ];
float value;
}; 可以用 fprintf
fprintf(pbooks, "%s. %s. %.2f\n", primer.title, primer.author, primer.value);fprintf + 固定宽度
fprintf(pbooks, "%39s%39s%8.2f\n", primer.title, primer.author, primer.value);保存二进制文件
以二进制表示法储存数据的缺点是,不同的系统可能使用不同的二进制表示法,所以数据文件可能不具可移植性。甚至同一个系统,不同编译器设置也可能导致不同的二进制布局。
fwrite(&primer, sizeof(struct book),l,pbooks); union
只能存一个变量的数组,推荐使用方式:结构+联合
struct owner {
char sosecurity[12];
...
};
struct leasecompany {
char name[40];
char headquarters[40];
...
};
union data {
struct owner owncar;
struct leasecompany leasecar;
};
struct car_data {
char make[15];
int status; /* 私有为0,租赁为1 */
union data ownerinfo;
...
};
enum
枚举,默认值是从 0 开始的 int,也可以自定义数值
enum week = {Mon, Tus, Wen, Thr, Fri, Sat, Sun};
enum levels = {lows = 100, medium = 500, high = 2000};Demo
/* enum.c -- uses enumerated values */
#include <stdio.h>
#include <string.h> // for strcmp(), strchr()
#include <stdbool.h> // C99 feature
char * s_gets(char * st, int n);
enum spectrum {red, orange, yellow, green, blue, violet};
const char * colors[] = {"red", "orange", "yellow",
"green", "blue", "violet"};
#define LEN 30
int main(void)
{
char choice[LEN];
enum spectrum color;
bool color_is_found = false;
puts("Enter a color (empty line to quit):");
while (s_gets(choice, LEN) != NULL && choice[0] != '\0')
{
for (color = red; color <= violet; color++)
{
if (strcmp(choice, colors[color]) == 0)
{
color_is_found = true;
break;
}
}
if (color_is_found)
switch(color)
{
case red : puts("Roses are red.");
break;
case orange : puts("Poppies are orange.");
break;
case yellow : puts("Sunflowers are yellow.");
break;
case green : puts("Grass is green.");
break;
case blue : puts("Bluebells are blue.");
break;
case violet : puts("Violets are violet.");
break;
}
else
printf("I don't know about the color %s.\n", choice);
color_is_found = false;
puts("Next color, please (empty line to quit):");
}
puts("Goodbye!");
return 0;
}
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'); // look for newline
if (find) // if the address is not NULL,
*find = '\0'; // place a null character there
else
while (getchar() != '\n')
continue; // dispose of rest of line
}
return ret_val;
}
typedef
typedef 是编译器解释的,#define 是预处理器解释的。
typedef+结构(上边结构里边)
复杂声明
int a[2][3];
数组明后边的[]和函数名后边的()具有相同优先级,他们优先级高于*
int *p[10]; // 含有十个指针的数组
int (*p)[10]; // 指向含有十个整数的数组的指针// 含有4 个指针的数组
int *p[4];
p[0] = &a[0][0];
p[1] = &a[0][1];
p[2] = &a[1][0];
p[3] = &a[1][1];
printf("%p %p %p %p\n", p[0], p[1], p[2], p[3]);
printf("%d %d %d %d\n", *p[0], *p[1], *p[2], *p[3]);
// 0x7ff7ba96b810 0x7ff7ba96b814 0x7ff7ba96b81c 0x7ff7ba96b820
// 11 12 21 22
// 指向数组的指针
int num[4] = {100, 200, 300, 400};
int(*q)[4] = num;
printf("%p, sizeof(int)=%u,sizeof(q)=%u, sizeof(*q)=%u\n", q, sizeof(int), sizeof(q), sizeof(*q));
printf("%d %d %d %d\n", (*q)[0], (*q)[1], (*q)[2], (*q)[3]);
// 0x7ff7be28a7e0, sizeof(int)=4,sizeof(q)=8, sizeof(*q)=16
// 100 200 300 400最后更新于
这有帮助吗?