共用体容许您在相同的内存位置存储不一样的数据类型。您能够定义一个带有多成员的共用体,可是任什么时候候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。html
为了定义共用体,您必须使用 union 语句,方式与定义结构体相似。union 语句定义了一个新的数据类型,带有多个成员。union 语句的格式以下:编程
union [union tag] { member definition; member definition; ... member definition; } [one or more union variables];
union tag 是可选的,每一个 member definition 是标准的变量定义,好比 int i; 或者 float f; 或者其余有效的变量定义。在共用体定义的末尾,最后一个分号以前,您能够指定一个或多个共用体变量,这是可选的。下面定义一个名为 Data 的共用体类型,有三个成员 i、f 和 str:编程语言
union Data { int i; float f; char str[20]; } data;
如今,Data 类型的变量能够存储一个整数、一个浮点数,或者一个字符串。这意味着一个变量(相同的内存位置)能够存储多个多种类型的数据。您能够根据须要在一个共用体内使用任何内置的或者用户自定义的数据类型。函数
共用体占用的内存应足够存储共用体中最大的成员。例如,在上面的实例中,Data 将占用 20 个字节的内存空间,由于在各个成员中,字符串所占用的空间是最大的。下面的实例将显示上面的共用体占用的总内存大小:this
#include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; printf( "Memory size occupied by data : %d\n", sizeof(data)); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:命令行
Memory size occupied by data : 20指针
为了访问共用体的成员,咱们使用成员访问运算符(.)。成员访问运算符是共用体变量名称和咱们要访问的共用体成员之间的一个句号。您可使用 union 关键字来定义共用体类型的变量。code
#include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 10; data.f = 220.5; strcpy( data.str, "C Programming"); printf( "data.i : %d\n", data.i); printf( "data.f : %f\n", data.f); printf( "data.str : %s\n", data.str); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:orm
data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programminghtm
在这里,咱们能够看到共用体的 i 和 f 成员的值有损坏,由于最后赋给变量的值占用了内存位置,这也是 str 成员可以无缺输出的缘由。如今让咱们再来看一个相同的实例,此次咱们在同一时间只使用一个变量,这也演示了使用共用体的主要目的:
#include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 10; printf( "data.i : %d\n", data.i); data.f = 220.5; printf( "data.f : %f\n", data.f); strcpy( data.str, "C Programming"); printf( "data.str : %s\n", data.str); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:
data.i : 10
data.f : 220.500000
data.str : C Programming
在这里,全部的成员都能无缺输出,由于同一时间只用到一个成员。
typedef 关键字,您可使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE:
typedef unsigned char BYTE;
在这个类型定义以后,标识符 BYTE 可做为类型 unsigned char 的缩写,例如:
BYTE b1, b2;
按照惯例,定义时会大写字母,以便提醒用户类型名称是一个象征性的缩写,但您也可使用小写字母。
您也可使用 typedef 来为用户自定义的数据类型取一个新的名字。例如,您能够对结构体使用 typedef 来定义一个新的数据类型名字,而后使用这个新的数据类型来直接定义结构变量,以下:
#include <stdio.h> #include <string.h> typedef struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } Book; int main( ) { Book book; strcpy( book.title, "C 教程"); strcpy( book.author, "Runoob"); strcpy( book.subject, "编程语言"); book.book_id = 12345; printf( "书标题 : %s\n", book.title); printf( "书做者 : %s\n", book.author); printf( "书类目 : %s\n", book.subject); printf( "书 ID : %d\n", book.book_id); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:
书标题 : C 教程
书做者 : Runoob
书类目 : 编程语言
书 ID : 12345
#define 是 C 指令,用于为各类数据类型定义别名,与 typedef 相似,可是它们有如下几点不一样:
下面是 #define 的最简单的用法:
#include <stdio.h> #define TRUE 1 #define FALSE 0 int main( ) { printf( "TRUE 的值: %d\n", TRUE); printf( "FALSE 的值: %d\n", FALSE); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:
TRUE 的值: 1
FALSE 的值: 0
当咱们提到输入时,这意味着要向程序填充一些数据。输入能够是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据须要填充到程序中。
当咱们提到输出时,这意味着要在屏幕上、打印机上或任意文件中显示一些数据。C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件中。
C 语言把全部的设备都看成文件。因此设备(好比显示器)被处理的方式与文件相同。如下三个文件会在程序执行时自动打开,以便访问键盘和屏幕。
标准文件 | 文件指针 | 设备 |
---|---|---|
标准输入 | stdin | 键盘 |
标准输出 | stdout | 屏幕 |
标准错误 | stderr | 您的屏幕 |
文件指针是访问文件的方式,本节将讲解如何从屏幕读取值以及如何把结果输出到屏幕上。
C 语言中的 I/O (输入/输出) 一般使用 printf() 和 scanf() 两个函数。
scanf() 函数用于从标准输入(键盘)读取并格式化, printf() 函数发送格式化输出到标准输出(屏幕)。
#include <stdio.h> // 执行 printf() 函数须要该库 int main() { printf("c语言教程"); //显示引号中的内容 return 0; }
编译以上程序,输出结果为:
c语言教程
实例解析:
%d 格式化输出整数
#include <stdio.h> int main() { int testInteger = 5; printf("Number = %d", testInteger); return 0; }
编译以上程序,输出结果为:
Number = 5
在 printf() 函数的引号中使用 "%d" (整型) 来匹配整型变量 testInteger 并输出到屏幕。
%f 格式化输出浮点型数据
#include <stdio.h> int main() { float f; printf("Enter a number: "); // %f 匹配浮点型数据 scanf("%f",&f); printf("Value = %f", f); return 0; }
int getchar(void) 函数从屏幕读取下一个可用的字符,并把它返回为一个整数。这个函数在同一个时间内只会读取一个单一的字符。您能够在循环内使用这个方法,以便从屏幕上读取多个字符。
int putchar(int c) 函数把字符输出到屏幕上,并返回相同的字符。这个函数在同一个时间内只会输出一个单一的字符。您能够在循环内使用这个方法,以便在屏幕上输出多个字符。
请看下面的实例:
#include <stdio.h> int main( ) { int c; printf( "Enter a value :"); c = getchar( ); printf( "\nYou entered: "); putchar( c ); printf( "\n"); return 0; }
当上面的代码被编译和执行时,它会等待您输入一些文本,当您输入一个文本并按下回车键时,程序会继续并只会读取一个单一的字符,显示以下:
$./a.out
Enter a value :runoobYou entered: r
char *gets(char *s) 函数从 stdin(键盘) 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout(屏幕)。
#include <stdio.h> int main( ) { char str[100]; printf( "Enter a value :"); gets( str ); printf( "\nYou entered: "); puts( str ); return 0; }
当上面的代码被编译和执行时,它会等待您输入一些文本,当您输入一个文本并按下回车键时,程序会继续并读取一整行直到该行结束,显示以下:
$./a.out
Enter a value :runoobYou entered: runoob
int scanf(const char *format, ...) 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。
int printf(const char *format, ...) 函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。
format 能够是一个简单的常量字符串,可是您能够分别指定 %s、%d、%c、%f 等来输出或读取字符串、整数、字符或浮点数。还有许多其余可用的格式选项,能够根据须要使用。经过下面这个简单的实例来加深理解:
#include <stdio.h> int main( ) { char str[100]; int i; printf( "Enter a value :"); scanf("%s %d", str, &i); printf( "\nYou entered: %s %d ", str, i); printf("\n"); return 0; }
当上面的代码被编译和执行时,它会等待您输入一些文本,当您输入一个文本并按下回车键时,程序会继续并读取输入,显示以下:
$./a.out
Enter a value :runoob 123You entered: runoob 123
在这里,应当指出的是,scanf() 期待输入的格式与您给出的 %s 和 %d 相同,这意味着您必须提供有效的输入,好比 "string integer",若是您提供的是 "string string" 或 "integer integer",它会被认为是错误的输入。另外,在读取字符串时,只要遇到一个空格,scanf() 就会中止读取,因此 "this is test" 对 scanf() 来讲是三个字符串。