文章目录

  • Structures
    • Declarations Using Structures
    • Accessing Structure Members
    • Using typedef
  • Working With Structures
    • Structures with Structures
    • Pointers to Structures
    • Structures as Function Parameters
    • Array of Structures(未完)
  • Unions
    • Accessing Union Members
    • Structures With Unions
  • Working With Unions
    • Pointers to Unions
    • Unions as Function Parameters
    • Array of Unions

Structures

A structure is a user-defined data type that groups related variables of different data types.

A structure declaration includes the keyword struct, a structure tag for referencing the structure, and curly braces { } with a list of variable declarations called members.
For example:

struct course {int id;char title[40];float hours;
};

This struct statement defines a new data type named course that has three members.
Structure members can be of any data type, including basic types, strings, arrays, pointers, and even other structures, as you will learn in a later lesson.
Do not forget to put a semicolon after structure declaration.
A structure is also called a composite or aggregate data type. Some languages refer to structures as records.

Declarations Using Structures

To declare variables of a structure data type, you use the keyword struct followed by the struct tag, and then the variable name.
For example, the statements below declares a structure data type and then uses the student struct to declare variables s1 and s2

#include <stdio.h>struct student {int age;int grade;char name[40];
};int main() {/* declare two variables */struct student s1;struct student s2;s1.age = 19;s1.grade = 9;sprintf(s1.name, "John Bighimer");s2.age = 22;s2.grade = 10;sprintf(s2.name, "Batman Jokerson");printf("Student: %s, %d\n", s1.name, s1.age);printf("Student: %s, %d\n", s2.name, s2.age);return 0;
}

A struct variable is stored in a contiguous block of memory. The sizeof operator must be used to get the number of bytes needed for a struct, just as with the basic data types.

A struct variable can also be initialized in the declaration by listing initial values in order inside curly braces:

#include <stdio.h>struct student {int age;int grade;char name[40];
};int main() {/* declare two variables */struct student s1 = {19, 9, "John Birghimer"};struct student s2 = {22, 10, "Batman Jokerson"};printf("Student: %s, %d\n", s1.name, s1.age);printf("Student: %s, %d\n", s2.name, s2.age);return 0;
}

If you want to initialize a structure using curly braces after declaration, you will also need to typecast, as in the statements:

#include <stdio.h>struct student {int age;int grade;char name[40];
};int main() {struct student s1; // declaring// type cast neededs1= (struct student){19, 9, "John Birghimer"};printf("Student: %s, %d\n", s1.name, s1.age);return 0;
}

You can use named member initialization when initializing a structure to initialize corresponding members:

#include <stdio.h>struct student {int age;int grade;char name[40];
};int main() {struct student s1 = { .grade = 9, .age = 19, .name = "John Birghimer"};printf("Name: %s, Age: %d, Grade: %d\n", s1.name, s1.age, s1.grade);return 0;
}

In the example above, .grade refers to the grade member of the structure. Similarly, .age and .name refer to the age and name members.

Accessing Structure Members

You access the members of a struct variable by using the . (dot operator) between the variable name and the member name.
For example, to assign a value to the age member of the s1 struct variable, use a statement like:

s1.age = 19;

You can also assign one structure to another of the same type:

#include <stdio.h>struct student {int age;int grade;char name[40];
};int main() {struct student s1 = {19, 9, "Jason"};struct student s2;printf("Assigning, s2 = s1\n");s2 = s1;printf("Results, Name: %s, Age: %d, Grade: %d\n", s2.name, s2.age, s2.grade);return 0;
}

The following code demonstrates using a structure:

#include <stdio.h>
#include <string.h>struct course {int id;char title[40];float hours;
};int main() {struct course cs1 = {341279, "Intro to C++", 12.5};struct course cs2;/* initialize cs2 */cs2.id = 341281;strcpy(cs2.title, "Advanced C++");cs2.hours = 14.25;/* display course info */printf("%d\t%s\t%4.2f\n", cs1.id, cs1.title, cs1.hours);printf("%d\t%s\t%4.2f\n", cs2.id, cs2.title, cs2.hours);return 0;
}

String assignment requires strcpy() from the string.h library.
Also note the format specifiers %4.2f include width and precision options.

Using typedef

The typedef keyword creates a type definition that simplifies code and makes a program easier to read.
typedef is commonly used with structures because it eliminates(消除) the need to use the keyword struct when declaring variables.
For example:

#include <stdio.h>
#include <string.h>typedef struct {int id;char title[40];float hours;
} course;int main() {course cs1;course cs2;cs1.id = 123456;strcpy(cs1.title, "JavaScript Basics");cs1.hours = 12.30;/* initialize cs2 */cs2.id = 341281;strcpy(cs2.title, "Advanced C++");cs2.hours = 14.25;/* display course info */printf("%d\t%s\t%4.2f\n", cs1.id, cs1.title, cs1.hours);printf("%d\t%s\t%4.2f\n", cs2.id, cs2.title, cs2.hours);return 0;
}

Note that a structure tag is no longer used, instead a typedef name appears before the struct declaration.
Now the word struct is no longer required in variable declarations, making the code cleaner and easier to read.

Working With Structures

Structures with Structures

The members of a structure may also be structures.

#include <stdio.h>typedef struct {int x;int y;
} point;typedef struct {float radius;point center;
} circle; int main() {point p;p.x = 3;p.y = 4;circle c;c.radius = 3.14;c.center = p;printf("Circle radius is %.2f, center is at (%d, %d)", c.radius, c.center.x, c.center.y);return 0;
}

Nested curly braces are used to initialize members that are structs. The dot operator is used twice to access members of members, as in the statements:

#include <stdio.h>typedef struct {int x;int y;
} point;typedef struct {float radius;point center;
} circle; int main() {circle c = {4.5, {1, 3}};printf("%3.1f %d,%d", c.radius, c.center.x, c.center.y);/* 4.5  1,3 */return 0;
}

A struct definition must appear before it can be used inside another struct.

Pointers to Structures

Just like pointers to variables, pointers to structures can also be defined.

struct myStruct *struct_ptr;
defines a pointer to the myStruct structure.

struct_ptr = &struct_var;
stores the address of the structure variable struct_var in the pointer struct_ptr.

struct_ptr -> struct_mem;
accesses the value of the structure member struct_mem.

For example:

#include <stdio.h>
#include <string.h>// Student Structure Definition
struct student{char name[50];int number;int age;
};// Struct pointer as a function parameter
void showStudentData(struct student *st) {printf("\nStudent:\n");printf("Name: %s\n", st->name);printf("Number: %d\n", st->number);printf("Age: %d\n", st->age);
}int main() {// New Student Record Creationstruct student st1;struct student st2;// Filling Student 1 Detailsstrcpy(st1.name, "Krishna");st1.number = 5;st1.age = 21;// Filling Student 2 Detailsstrcpy(st2.name, "Max");st2.number = 9;st2.age = 15;// Displaying Student 1 DetailsshowStudentData(&st1);// Displaying Student 2 DetailsshowStudentData(&st2);return 0;
}

The -> operator allows to access members of the struct though the pointer.
(*st).age is the same as st->age.
Also, when a typedef has been used to name the struct, then a pointer is declared using only the typedef name along with * and the pointer name.

#include <stdio.h>
#include <string.h>// Student Structure Definition
typedef struct {char name[50];int number;int age;
}student;// Struct pointer as a function parameter
void showStudentData(student *st) {printf("\nStudent:\n");printf("Name: %s\n", st->name);printf("Number: %d\n", st->number);printf("Age: %d\n", st->age);
}int main() {// New Student Record Creationstudent st1;student st2;// Filling Student 1 Detailsstrcpy(st1.name, "Krishna");st1.number = 5;st1.age = 21;// Filling Student 2 Detailsstrcpy(st2.name, "Max");st2.number = 9;st2.age = 15;// Displaying Student 1 DetailsshowStudentData(&st1);// Displaying Student 2 DetailsshowStudentData(&st2);return 0;
}

Why pointers? Passing a struct to a function as a value is a poor code practice. Pointers exist for many reasons and one of them is efficiency. A struct is normally a big chunk of memory (containing strings, arrays, double variables, other structures…), so, if you are not using a pointer to pass it to a function, you end up to copy every single byte of that struct again and again for every function call. This means memory overload, slow processing time and inefficiency. But pointers help us! A struct passed by reference (i.e. with a pointer that is basically an address) to a function, won’t be copied but just referenced. This mechanism saves a lot of memory and time.

struct Point {int x;int y;} p1;struct Point *ptr = &p1;ptr->x = 3;ptr->y = 4;

This is how you can declare a variable (p1) instead of writing struct Point p1; If you used typedef it’d look like this:

typedef struct {int x; int y;
} Point;
// But then you'd need to add:
Point p1;

In this case also, i’d be: Point *ptr = &p1; omitting the “struct”.

Structures as Function Parameters

A function can have structure parameters that accept arguments by value when a copy of the structure variable is all that is needed.
For a function to change the actual values in a struct variable, pointer parameters are required.

For example:

#include <stdio.h>
#include <string.h>typedef struct {int id;char title[40];float hours;
} course;void update_course(course *class);
void display_course(course class);int main() {course cs2;update_course(&cs2);display_course(cs2);return 0;
}void update_course(course *class) {strcpy(class->title, "C++ Fundamentals");class->id = 111;class->hours = 12.30;
}void display_course(course class) {printf("%d\t%s\t%3.2f\n", class.id, class.title, class.hours);
}

As you can see, update_course() takes a pointer as the parameter, while display_course() takes the structure by value.

When a function is called, a memory block is created in the temporary memory which is called stack. After the function is done, this memory block also vanishes. That’s why you can’t update a value which is outside of the function. if we want to update such a variable, we must pass the pointer. Literally that is the address of the variable.
The stack is largely used also when we have a recursive functions.

Array of Structures(未完)

An array can store elements of any data type, including structures.
After declaring an array of structures, an element is accessible with the index number.
The dot operator is then used to access members of the element, as in the program:

#include <stdio.h>
typedef struct {int h;int w;int l;
} box;
int main() {box boxes[3] = {{2, 6, 8}, {4, 6, 6}, {2, 6, 9}};int k, volume;for (k = 0; k < 3; k++) {volume = boxes[k].h*boxes[k].w*boxes[k].l;printf("box %d volume %d\n", k, volume);}return 0;
}

Arrays of structures are used for data structures such as linked lists, binary trees, and more.

When you are implementing high performance applications, some times using “Structure of arrays” is preferred to “Array of structures” because of data locality.

  • 待添加评论里的内容

Unions

A union allows to store different data types in the same memory location.
It is like a structure because it has members. However, a union variable uses the same memory location for all its member’s and only one member at a time can occupy the memory location.

A union declaration uses the keyword union, a union tag, and curly braces { } with a list of members.

Union members can be of any data type, including basic types, strings, arrays, pointers, and structures.
For example:

#include <stdio.h>union val {int int_num;float fl_num;char str[20];
};int main() {union val test;test.int_num = 42;printf("%d", test.int_num);return 0;
}

After declaring a union, you can declare union variables. You can even assign one union to another of the same type:

#include <stdio.h>union val {int int_num;float fl_num;char str[20];
};int main() {union val u1;union val u2;u1.int_num = 42;u2 = u1;printf("%d", u2.int_num);return 0;
}

Unions are used for memory management. The largest member data type is used to determine the size of the memory to share and then all members use this one location. This process also helps limit memory fragmentation. Memory management is discussed in a later lesson.

Accessing Union Members

You access the members of a union variable by using the . dot operator between the variable name and the member name.
When assignment is performed, the union memory location will be used for that member until another member assignment is performed.

Trying to access a member that isn’t occupying the memory location gives unexpected results.

The following program demonstrates accessing union members:

#include <stdio.h>union val {int int_num;float fl_num;char str[20];
};
int main() {  union val test;test.int_num = 123;test.fl_num = 98.76;strcpy(test.str, "hello");printf("%d\n", test.int_num);printf("%f\n", test.fl_num);printf("%s\n", test.str);return 0;
}

The last assignment overrides(覆盖) previous assignments, which is why str stores a value and accessing int_num and fl_num is meaningless.

The results of accessing a union with a variable of different type are not unexpected or random, but predictable and meaningful. Storing some value at a memory location stores the value there in a format specific to the type, but interpreting the value in the format of a different type is straightforward. In the example given, we store the string ‘hello’ and access the same memory location as an int, which results in 1819043176 = 104 (‘h’) + 2^8 * 101 (‘e’) + 2^16 * 108 (‘l’) + 2^24 * 108 (‘l’) This is just the way the ASCII values of the string’s first 4 characters are interpreted as an integer in little Endian format.
An int is made up of only 4 bytes. So just the first four bytes (‘hell’) will be read. The rest is ignored by an int.

Just like struct, you can TYPEDEF union.

typedef union { ...
} val;
val variable = ..; /* saves one 'union' in each declaring */

Structures With Unions

Unions are often used within structures because a structure can have a member to keep track of(跟踪) which union member stores a value.
For example, in the following program, a vehicle struct uses either a vehicle identification number (VIN) or an assigned id, but not both:

#include <stdio.h>
#include <string.h>typedef struct {char make[20];int model_year;int id_type; /* 0 for id_num, 1 for VIN */union {int id_num;char VIN[20]; } id;
} vehicle;int main() {  vehicle car1;strcpy(car1.make, "Ford");car1.model_year = 2017;car1.id_type = 0;car1.id.id_num = 123098;printf("Car %s, %d", car1.make, car1.model_year);return 0;
}

Note that the union was declared inside the structure. When doing this, a union name was required at the end of the declaration.
A union with a union tag could have been declared outside the structure, but with such a specific use, the union within the struct provides easier to understand the code.

Note also the dot operator is used twice to access union members of struct members.

The id_type keeps track of which union member stores a value. The following statements display car1 data, using the id_type to determine which union member to read:

#include <stdio.h>
#include <string.h>typedef struct {char make[20];int model_year;int id_type; /* 0 for id_num, 1 for VIN */union {int id_num;char VIN[20]; } id;
} vehicle;int main() {  vehicle car1;strcpy(car1.make, "Ford");car1.model_year = 2017;car1.id_type = 0;car1.id.id_num = 123098;printf("Make: %s\n", car1.make);printf("Model Year: %d\n", car1.model_year);if (car1.id_type == 0)printf("ID: %d\n", car1.id.id_num);elseprintf("ID: %s\n", car1.id.VIN);return 0;
}

A union can also contain a structure.
If you are using C11 standard (2011 C ISO Version), then you do not have to name the union in a struct. You can also not name a structure. This is known as an anonymous union/struct and in the example here it will allow you to drop the .id of the car.id.id_num and just do car.id_num which is more readable.

Working With Unions

Pointers to Unions

A pointer to a union points to the memory location allocated(分配) to the union.
A union pointer is declared by using the keyword union and the union tag along with * and the pointer name.
For example, consider the following statements:

#include <stdio.h>
#include <string.h>union val {int int_num;float fl_num;char str[20];
};int main() {  union val info;union val *ptr = NULL;ptr = &info;ptr->int_num = 10;printf("info.int_num is %d", info.int_num);return 0;
}

When you want to access the union members through a pointer, the -> operator is required.
(*ptr).int_num is the same as ptr->int_num.

Unions as Function Parameters

A function can have union parameters that accept arguments by value when a copy of the union variable is all that is needed.

For a function to change the actual value in a union memory location, pointer parameters are required.
For example:

#include <stdio.h>
#include <string.h>union id {int id_num;char name[20];
};void set_id (union id *item);
void show_id (union id item);int main() {  union id item;set_id(&item);  show_id(item);return 0;
}void set_id(union id *item) {item->id_num = 42;
}void show_id(union id item) {printf("ID is %d", item.id_num);
}

Array of Unions

An array can store elements of any data type, including unions.
With unions, it is important to keep in mind that only one member of the union can store data for each array element.

After declaring an array of unions, an element is accessible with the index number. The dot operator is then used to access members of the union, as in the program:

#include <stdio.h>union val {int int_num;float fl_num;char str[20];
};int main() {  union val nums[10];int k;/* create an array of ints */for (k = 0; k < 10; k++) {nums[k].int_num = k;}/* display array values */for (k = 0; k < 10; k++) {printf("%d  ", nums[k].int_num);}return 0;
}

An array is a data structure that stores collection values that are all the same type. Arrays of unions allow storing values of different types.
For example:

#include <stdio.h>union type {int i_val;float f_val;char ch_val;
};int main() {union type arr[3];arr[0].i_val = 42;arr[1].f_val = 3.14;arr[2].ch_val = 'x';printf("1st element is %d, 2nd is %f, and the 3rd is %c", arr[0].i_val, arr[1].f_val, arr[2].ch_val);return 0;
}

C语言第五章Structures Unions相关推荐

  1. c语言逐步搜索法求有根区间,[C语言第五章.ppt

    [C语言第五章 算法举例 基本思想是,根据提出的问题,列举所有可能的情况,并 用问题中给定的条件检验哪些是需要的,哪些是不需要的. 教学进程 列举与试探 列举法常用于解决"是否存在" ...

  2. c语言每个整数占9列,c语言 第五章 数据类型和表达式.ppt

    c语言 第五章 数据类型和表达式 第五章数据类型和表达式 C语言的基本数据类型 各种基本数据类型的常量和变量的定义 C语言的表达式和各种表达式的求解规则 5.1 数据的存储和基本数据类型 5.1.1数 ...

  3. C语言第五章实验原理,C语言第五章实验报告.docx

    C语言第五章实验报告 C语言第五章实验报告?班级:14金工3班??????????学号???????????姓名:周俐俐一.实验目的?1.?熟悉C语言编程环境.2.?进一步熟悉用C语言调试C语言源程序 ...

  4. C语言 第五章 选择结构 答案,c语言第五章 选择结构程序设计(习题册答案).doc

    第五章 选择结构程序设计 基础练习(A) 一.填空题 1.关系表达式的运算结果是 逻辑 值.C语言没有逻辑型数据,以 1 代表"真",以 0代表"假". 2.逻 ...

  5. c语言第五章作业,《C语言程序设计》第五章作业.doc

    <C语言程序设计>第五章作业 窗体顶端 <C语言程序设计>第5章作业 布置日期:2012-3-15?????截止日期:2012-3-22 一. 单选题 (每小题6分,共102分 ...

  6. c语言定义int 输出4386,大学C语言第五章课后习题参考程序

    考试,二级C语言备考 第五章课后习题参考程序 5.1 编写程序,求100-2000之间所有3的倍数之和,当和大于1000时结束. (参考答案:900) #include int main() { in ...

  7. 信息学奥赛一本通(C++版)第一部分 C++语言 第五章 数组

    第五章 数组 第一节 一维数组 T1102 : 与指定数字相同的数的个数 时间限制: 1000 ms 内存限制: 65536 KB [题目描述]   输出一个整数序列中与指定数字相同的数的个数. [输 ...

  8. 2022SDUT知到/智慧树----C语言第五章测试题解(答案~)大家看清顺序

    第五章测试-答案已加粗 1[判断题](10分) 在C语言中,逻辑运算符"&&"比"||"的优先级高(). A.对 B.错 参考答案:A 2[判断 ...

  9. 猴子第一天摘下若干个桃子,当时吃了一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个谭浩强c语言第五章第十二题

    题目 本题是谭浩强<c语言程序设计>第五章第十二题 题目:猴子第一天摘下若干个桃子,当时吃了一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上再想吃时,就只剩一个 ...

最新文章

  1. Python 列表 sort() 方法
  2. jquerynbsp;easyuinbsp;dateboxnbsp;的使用nbsp;.
  3. Python TVTK 标量数据可视化与矢量数据可视化,空间轮廓线可视化
  4. CSS的!important属性修改权重
  5. *第十五周*数据结构实践项目二【用哈希法组织关键字】
  6. 关于Idea模块化部署web项目,Web Resource Directories作用
  7. java给出汉字“你”“我”“他”在Unicode表中的位置
  8. 图书馆管理系统前景与范围文档
  9. matlab画图画点画直线
  10. Linux 硬盘故障修复
  11. 钱我所欲也,健康我所欲也,舍钱而取健康也
  12. 51单片机——ADC模数转换、DAC数模转换PWM C语言入门编程
  13. 【软件分析/静态程序分析学习笔记】5.数据流分析基础(Data Flow Analysis-Foundations)
  14. 京东商品图片 自动下载 抓取 c# 爬虫
  15. 基于情感词典的python情感分析!它居然比我还懂我女友!
  16. 【总目录】人工智能、机器学习、深度学习总结大全----目录.未完待续...
  17. C++ STL之命名空间、函数模板、类模板
  18. 560万Facebook人际关系数据,揭秘家庭职业传承“真相”
  19. [转]Unicode 汉字数据库
  20. 学会Nginx优化与防盗链预防坏蜀黍

热门文章

  1. Echarts的常用api
  2. 【找出耗电大户进行消灭 电池持久有绝招】
  3. c语言while if嵌套,C语言循环嵌套详解
  4. Python | 分析txt文档特定词汇的词频,以《天龙八部》为例
  5. transformers的近期工作成果综述
  6. 使用NHibernate 3.2实现Repository(ORuM)(三)NHibernate、Mapping、Mapping-By-Code
  7. 使用github+Hexo人人都能拥有一个美美的博客
  8. 29、浏览器缓存的原理
  9. java中JAO_JVM内部细节之一:synchronized关键字及实现细节(轻量级锁Lightweight Locking)...
  10. solar在linux系统下的部署过程