今天咱们继续来学习C语言的入门知识点程序员
任何一种编程中,做用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方能够声明变量:spring
在函数或块内部的局部变量编程
在全部函数外部的全局变量数组
在形式参数的函数参数定义中微信
让咱们来看看什么是局部变量、全局变量和形式参数。数据结构
局部变量dom
在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。下面是使用局部变量的实例。在这里,全部的变量 a、b 和 c 是 main() 函数的局部变量。编程语言
void main(){函数
//局部变量学习
int a, b;
int c;
//初始化局部变量
a = 10;
b = 20;
c = a + b;
//%d:以十进制形式输出带符号整数(正数不输出符号)
printf("values of a = %d,b = %d and c = %d \n", a, b, c);
}
输出:values of a = 10,b = 20 and c = 30
全局变量
全局变量是定义在函数外部,一般是在程序的顶部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。
全局变量能够被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。下面是使用全局变量和局部变量的实例:
//全局变量声明
int g;
void main(){
int a, b;
//初始化局部变量
a = 10;
b = 20;
//所有变量赋值
g = a + c;
printf("values of a = %d,bc = %d and g = %d \n", a, c, g);
}
输出:values of a = 10,bc = 30 and g = 40
形式参数
函数的参数,形式参数,被看成该函数内的局部变量,若是与全局变量同名它们会优先使用。下面是一个实例:
int sumA(int a, int b) {
printf("value of a in sum() = %d\n", a);
printf("value of b in sum() = %d\n", b);
return x + y;
}
void main(){
int a, b,c;
//初始化局部变量
a = 10;
b = 20;
c = sumA(a, b);
printf("value of c in main() = %d\n", c);
}
输出:value of a in main() = 30
全局变量和局部变量的区别
(1)全局变量保存在内存的全局存储区中,占用静态的存储单元;
(2)局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
初始化局部变量和全局变量的默认值
C 语言支持数组数据结构,它能够存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它每每被认为是一系列相同类型的变量。
数组的声明并非声明一个个单独的变量,好比 number0、number一、...、number99,而是声明一个数组变量,好比 numbers,而后使用 numbers[0]、numbers[1]、...、numbers[99] 来表明一个个单独的变量。数组中的特定元素能够经过索引访问。
全部的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
声明数组
在 C 中要声明一个数组,须要指定元素的类型和元素的数量,以下所示:
type arrayName [ arraySize ];
这叫作一维数组。arraySize 必须是一个大于零的整数常量,type 能够是任意有效的 C 数据类型。例如,要声明一个类型为 double 的包含 10 个元素的数组 balance,声明语句以下:
double balance[10];
初始化数组
void main(){
double balance[10] = {1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0}
}
大括号 { } 之间的值的数目不能大于咱们在数组声明时在方括号 [ ] 中指定的元素数目。
若是您省略掉了数组的大小,数组的大小则为初始化时元素的个数。所以,若是:
void main(){
double balance[] = {1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0}
}
您将建立一个数组,它与前一个实例中所建立的数组是彻底相同的。下面是一个为数组中某个元素赋值的实例:
balance[1] = 50.5;
访问数组元素
//跟 Java 同样
double value = balance[1]
例子:
void main() {
//定义一个长度为 10 的整数数组
int n[10];
int i, j;
//初始化数组元素
for (i = 0; i < 10; i++) {
n[i] = 2 * i;
}
//输出元素中的数据
for (int k = 0; k < 10; ++k) {
printf("Element[%d] = %d \n", k, n[k]);
}
//总的大小除以其中一个大小就获得了 数组长度
printf("整数数组 n 的长度: %d \n", sizeof(n) / sizeof(n[0]));
//输出元素中的数据
for (int k = 0; k < sizeof(n) / sizeof(n[0]); ++k) {
printf("Element[%d] = %d \n", k, n[k]);
}
}
输出:
Element[0] = 0
Element[1] = 2
Element[2] = 4
Element[3] = 6
Element[4] = 8
Element[5] = 10
Element[6] = 12
Element[7] = 14
Element[8] = 16
Element[9] = 18
整数数组 n 的长度: 10
Element[0] = 0
Element[1] = 2
Element[2] = 4
Element[3] = 6
Element[4] = 8
Element[5] = 10
Element[6] = 12
Element[7] = 14
Element[8] = 16
Element[9] = 18
C 中数组详解
在 C 中,数组是很是重要的,咱们须要了解更多有关数组的细节。下面列出了 C 程序员必须清楚的一些与数组相关的重要概念:
枚举是 C 语言中的一种基本数据类型,它可让数据更简洁,更易读。
枚举语法定义格式为:
enum 枚举名 {枚举元素1,枚举元素2,……};
接下来咱们举个例子,好比:一星期有 7 天,若是不用枚举,咱们须要使用 #define 来为每一个整数定义一个别名:
#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7
这个看起来代码量就比较多,接下来咱们看看使用枚举的方式:
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
这样看起来是否是更简洁了。
**注意:**第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。咱们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。
能够在定义枚举类型时改变枚举元素的值:
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5
枚举变量的定义
前面咱们只是声明了枚举类型,接下来咱们看看如何定义枚举变量。
咱们能够经过如下三种方式来定义枚举变量
一、先定义枚举类型,再定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
二、定义枚举类型的同时定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
三、省略枚举名称,直接定义枚举变量
enum
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
学习 C 语言的指针既简单又有趣。经过指针,能够简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是没法执行的。因此,想要成为一名优秀的 C 程序员,学习指针是颇有必要的。
正如您所知道的,每个变量都有一个内存位置,每个内存位置都定义了可以使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:
void main(){
int var1;
char var2[10];
//%p : 输出指针地址
printf("var1 变量的地址:%p \n", &var1);
printf("var2 变量的地址:%p \n", &var2);
}
输出:
var1 变量的地址:0x7ffee7e976b8
var2 变量的地址:0x7ffee7e976be
经过上面的实例,咱们了解了什么是内存地址以及如何访问它。接下来让咱们看看什么是指针。
什么是指针?
指针是一个变量,其值为另外一个变量的地址,即内存位置的直接地址。就像其余变量或常量同样,您必须在使用指针存储其余变量地址以前,对其进行声明。指针变量声明的通常形式为:
type *var-name
在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。可是,在这个语句中,星号是用来指定一个变量是指针。如下是有效的指针声明:
int *i; //一个整型的指针
double *d;//double 型指针
float *f;//浮点型指针
char *ch//字符型指针
全部实际数据类型,不论是整型、浮点型、字符型,仍是其余的数据类型,对应指针的值的类型都是同样的,都是一个表明内存地址的长的十六进制数。
不一样数据类型的指针之间惟一的不一样是,指针所指向的变量或常量的数据类型不一样。
如何使用指针?
使用指针时会频繁进行如下几个操做:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是经过使用一元运算符 ***** 来返回位于操做数所指定地址的变量的值。下面的实例涉及到了这些操做:
例子:
//如何使用指针
int var = 66;//实际变量的声明
int *ip;//指针变量的声明
ip = &var; //指针变量中存储 var 的地址
printf("var 的地址 : %p \n", var);
//在指针变量中存储的地址
printf("ip 的地址:%p \n", ip);
//使用指针访问地址
printf("ip 指针对应的地址:%p \n", *ip);
//使用指针访问地址对应的值
printf("ip 指针对应的地址:%d \n", *ip);
输出:
var 的地址 : 0x42
ip 的地址:0x7ffee96eb6b4
ip 指针对应的地址:0x42
ip 指针对应的地址:66
C 中的 NULL 指针
在变量声明的时候,若是没有确切的地址能够赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:
void main(){
//赋值一个 NULL 指针
int *ptr = NULL;
printf("ptr 的地址是: %p \n", ptr);
//检查一个空指针
if (ptr) printf("若是 ptr 不是空指针,则执行"); else printf("若是 ptr 是空指针,则执行");
}
输出:ptr 的地址是: 0x0 ptr 是空指针
C 指针详解
在 C 中,有不少指针相关的概念,这些概念都很简单,可是都很重要。下面列出了 C 程序员必须清楚的一些与指针相关的重要概念:
函数指针是指向函数的指针变量。
一般咱们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
函数指针能够像通常函数同样,用于调用函数、传递参数。
函数指针变量的声明:
typedef int (*fun_ptr)(int,int)//声明一个指向一样参数,返回值得函数指针类型
回调函数
函数指针变量能够做为某个函数的参数来使用的,回调函数就是一个经过函数指针调用的函数。
简单讲:回调函数是由别人的函数执行时调用你实现的函数。
例子:
例子中 populate_array 函数定义了三个参数,其中第三个参数是函数的指针,经过该函数来设置数组的值。
实例中咱们定义了回调函数 getNextRandomValue,它返回一个随机值,它做为一个函数指针传递给 populate_array 函数。
populate_array 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。
#include <stdlib.h>
#include <stdio.h>
//回调函数
void populate_array(int *array, size_t arraySize, int(*getNextValue)(void)) {
printf("array 地址:%p \n", array);
for (size_t i = 0; i < arraySize; i++) {
array[i] = getNextValue();
printf(" array[%d] ,存储值:%d \n", i, array[i]);
}
}
//获取一个随机数
int getNextRandomValue(void) {
return rand();
}
void main() {
//回调函数
int array[10];
printf("Int array 地址:%p \n", array);
populate_array(array, sizeof(array)/sizeof(array[0]), getNextRandomValue);
for (int i = 0; i < sizeof(array)/sizeof(array[0]); ++i) {
printf(" array[%d] , 对应值为:%d \n", i, array[i]);
}
}
输出:
Int array 地址:0x7ffeebf1a650
array 地址:0x7ffeebf1a650
array[0] ,存储值:16807
array[1] ,存储值:282475249
array[2] ,存储值:1622650073
array[3] ,存储值:984943658
array[4] ,存储值:1144108930
array[5] ,存储值:470211272
array[6] ,存储值:101027544
array[7] ,存储值:1457850878
array[8] ,存储值:1458777923
array[9] ,存储值:2007237709
array[0] , 对应值为:16807
array[1] , 对应值为:282475249
array[2] , 对应值为:1622650073
array[3] , 对应值为:984943658
array[4] , 对应值为:1144108930
array[5] , 对应值为:470211272
array[6] , 对应值为:101027544
array[7] , 对应值为:1457850878
array[8] , 对应值为:1458777923
array[9] , 对应值为:2007237709
在 C 语言中,字符串其实是使用null字符 '\0' 终止的一维字符数组。所以,一个以 null 结尾的字符串,包含了组成字符串的字符。
下面的声明和初始化建立了一个 "Hello" 字符串。因为在数组的末尾存储了空字符,因此字符数组的大小比单词 "Hello" 的字符数多一个。
char ch[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
也可使用如下简写模式:
char ch[6] = "Hello"
字符串在 C/C++ 中内存表示:
其实,您不须要把 null 字符放在字符串常量的末尾。C 编译器会在初始化数组时,自动把 '\0' 放在字符串的末尾。让咱们尝试输出上面的字符串:
void main(){
//定义一个 char 数组
char string[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
//简写
char string2[6] = "Hello";
//%s:输出字符串
printf("string message : %s\n", string);
}
输出:string message : Hello
C 中对字符串操做的 API
C 数组容许定义可存储相同类型数据项的变量,结构是 C 编程中另外一种用户自定义的可用的数据类型,它容许您存储不一样类型的数据项。
结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能须要跟踪每本书的下列属性:
(1)Title
(2)Author
(3)Subject
(4)Book ID
定义结构
为了定义结构,您必须使用struct语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式以下:
struct name{
member-list;
member-list;
...
}name_tag,
name是结构的标签。
member-list是标准的变量定义,好比 int i;或者 float f,或者其它有效的变量定义。
name_tag结构变量,定义在结构的末尾,最后一个分号以前,你能够指定一个或多个结构变量,下面是声明 Book 的结构方式:
struct Books{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
注意:在定义结构体的时候name、member-list、name_tag 这 3 部分至少要出现 2 个。
结构体变量的初始化
和其它类型变量同样,在初始化的时候能够指定初始值。
//定义一个 Books 结构,相似于 Java 中的数据 bean
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
double rmb;
} book = {"Java", "Android", "C 语言", 666, 55.5};
void main(){
//打印 Books
printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\nrmb: %f\n", book.title,
book.author, book.subject, book.book_id, book.rmb);
}
输出:
title : Java
author: Android
subject: C 语言
book_id: 666
rmb: 55.500000
访问结构成员
struct Books2 {
char title[50];
char author[50];
char subject[100];
int book_id;
};
void main(){
//访问 Books2 结构成员
struct Books2 Books2A;//声明 Books2A 类型为 Books2
struct Books2 Books2B;//声明 Books2B 类型为 Books2
//Books2A 详述
strcpy(Books2A.title, "C Plus");
strcpy(Books2A.author, "Nuha Ali");
strcpy(Books2A.subject, "C");
Books2A.book_id = 666888;
//Books2B 详述
strcpy(Books2B.title, "C++ Plus");
strcpy(Books2B.author, "DevYK");
strcpy(Books2B.subject, "C++");
Books2B.book_id = 666999;
// 输出 Book1 信息
printf("Book 1 title : %s\n", Books2A.title);
printf("Book 1 author : %s\n", Books2A.author);
printf("Book 1 subject : %s\n", Books2A.subject);
printf("Book 1 book_id : %d\n", Books2A.book_id);
// 输出 Book2 信息
printf("Book 2 title : %s\n", Books2B.title);
printf("Book 2 author : %s\n", Books2B.author);
printf("Book 2 subject : %s\n", Books2B.subject);
printf("Book 2 book_id : %d\n", Books2B.book_id);
}
输出:
Book 1 title : C Plus
Book 1 author : Nuha Ali
Book 1 subject : C
Book 1 book_id : 666888
Book 2 title : C++ Plus
Book 2 author : DevYK
Book 2 subject : C++
Book 2 book_id : 666999
结构做为函数参数
//函数声明
void printBook(struct Books2 books2);
void main(){
//访问 Books2 结构成员
struct Books2 Books2A;//声明 Books2A 类型为 Books2
struct Books2 Books2B;//声明 Books2B 类型为 Books2
//Books2A 详述 ,将 CPlus copy 到 title 中
strcpy(Books2A.title, "C Plus");
strcpy(Books2A.author, "Nuha Ali");
strcpy(Books2A.subject, "C");
Books2A.book_id = 666888;
//Books2B 详述
strcpy(Books2B.title, "C++ Plus");
strcpy(Books2B.author, "DevYK");
strcpy(Books2B.subject, "C++");
Books2B.book_id = 666999;
// 输出 Book1 信息
printf("Book 1 title : %s\n", Books2A.title);
printf("Book 1 author : %s\n", Books2A.author);
printf("Book 1 subject : %s\n", Books2A.subject);
printf("Book 1 book_id : %d\n", Books2A.book_id);
// 输出 Book2 信息
printf("Book 2 title : %s\n", Books2B.title);
printf("Book 2 author : %s\n", Books2B.author);
printf("Book 2 subject : %s\n", Books2B.subject);
printf("Book 2 book_id : %d\n", Books2B.book_id);
printf("\n\n\n");
//结构做为函数参数
printBook(Books2A);
printBook(Books2B);
}
void printBook(struct Books2 book) {
printf("Book title : %s\n", book.title);
printf("Book author : %s\n", book.author);
printf("Book subject : %s\n", book.subject);
printf("Book book_id : %d\n", book.book_id);
}
输出:
Book 1 title : C Plus
Book 1 author : Nuha Ali
Book 1 subject : C
Book 1 book_id : 666888
Book 2 title : C++ Plus
Book 2 author : DevYK
Book 2 subject : C++
Book 2 book_id : 666999
Book title : C Plus
Book author : Nuha Ali
Book subject : C
Book book_id : 666888
Book title : C++ Plus
Book author : DevYK
Book subject : C++
Book book_id : 666999
指向结构的指针
您能够定义指向结构的指针,方式与定义指向其余类型变量的指针类似,以下所示:
struct Books *struct_pointer;
如今,您能够在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,以下所示:
struct_pointer = &Book1;
为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,以下所示:
struct_pointer->title;
例子:
//定义指向结构的指针
void printBookZZ(struct Books2 *books2);
void main(){
//访问 Books2 结构成员
struct Books2 Books2A;//声明 Books2A 类型为 Books2
struct Books2 Books2B;//声明 Books2B 类型为 Books2
//Books2A 详述 ,将 CPlus copy 到 title 中
strcpy(Books2A.title, "C Plus");
strcpy(Books2A.author, "Nuha Ali");
strcpy(Books2A.subject, "C");
Books2A.book_id = 666888;
//Books2B 详述
strcpy(Books2B.title, "C++ Plus");
strcpy(Books2B.author, "DevYK");
strcpy(Books2B.subject, "C++");
Books2B.book_id = 666999;
//经过内存地址传递信息,为了查找结构变量的地址,请把 & 运算符放在结构名称的前面
printBookZZ(&Books2A);
printBookZZ(&Books2B);
}
/**
* 为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,以下所示:
* @param book
*/
void printBookZZ(struct Books2 *book) {
printf("Book -> title : %s\n", book->title);
printf("Book -> author : %s\n", book->author);
printf("Book -> subject : %s\n", book->subject);
printf("Book -> book_id : %d\n", book->book_id);
}
位域
有些信息在存储时,并不须要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有 0 和 1 两种状态,用 1 位二进位便可。为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"。
所谓"位域"是把一个字节中的二进位划分为几个不一样的区域,并说明每一个区域的位数。每一个域有一个域名,容许在程序中按域名进行操做。这样就能够把几个不一样的对象用一个字节的二进制位域来表示。
典型的实例:
(1)用 1 位二进位存放一个开关量时,只有 0 和 1 两种状态。
(2)读取外部文件格式——能够读取非标准的文件格式。
位域ed 定义:
struct 位域结构名称{
位域列表
};
位域列表的形式为:类型说明符 位域名:位域长度
例:
struct bean {
int a:8;
int b:4;
int c:4;
}data;
说明 data 为 bean 变量,共占 2个字节。其中位域 a 占 8 位,位域 b 占 4 位,位域 c 占 4 位。
注意:
一个位域存储在同一个字节中,如一个字节所剩空间不够存放另外一位域时,则会从下一单元起存放该位域。也能够有意使某位域从下一单元开始。例如:
struct bean{
unsigned a:4;
unsigned :4;//空域
unsigned b:4;//从下一个单元开始存放
unsigned c:4;
}
在这个位域定义中共占用 2 个字节,a 占第一字节的 4 位,后 4 位填 0 表示不使用,b 从第二字节开始,占用 4 位,c 占用 4 位。
因为位域不容许跨两个字节,所以位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。若是最大长度大于计算机的整数字长,一些编译器可能会容许域的内存重叠,另一些编译器可能会把大于一个域的部分存储在下一个字中。
位域能够是无名位域,这时它只用来做填充或调整位置。无名的位域是不能使用的。例如:
struct k{
int a:1;
int :2; /* 该 2 位不能使用 */
int b:3;
int c:2;
};
从以上分析能够看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
位域的使用
位域的使用和结构成员的使用相同,其通常形式为:
(1)位域变量名.位域名
(2)位域变量名->位域名
位域容许用各类格式输出。
共用体是一种特殊的数据类型,容许您在相同的内存位置存储不一样的数据类型。您能够定义一个带有多成员的共用体,可是任什么时候候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。
定义共同体
为了定义共用体,您必须使用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 将占用 20 个字节的内存空间,由于在各个成员中,字符串所占用的空间是最大的。下面的实例将显示上面的共用体占用的总内存大小:
union Data {
int i;
float f;
char str[20];
};
void main(){
union Data data;
printf("Memory size occupied by data: %d\n", sizeof(data));
}
输出:Memory size occupied by data: 20
访问共同体成员
为了访问共用体的成员,咱们使用成员访问运算符(.)。成员访问运算符是共用体变量名称和咱们要访问的共用体成员之间的一个句号。您可使用 union 关键字来定义共用体类型的变量。下面的实例演示了共用体的用法:
union Data {
int i;
float f;
char str[20];
};
void main() {
//1. 访问共同体 no
data.i = 10;
data.f = 1314.520;
strcpy(data.str,"C/C++");
printf( "data.i : %d\n", data.i);
printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);
printf("\n\n\n");
//2. 访问共同体 yes
data.i = 10;
printf( "data.i : %d\n", data.i);
data.f = 1314.520;
printf( "data.f : %f\n", data.f);
strcpy(data.str,"C/C++");
printf( "data.str : %s\n", data.str);
}
输出:
data.i : 725823299
data.f : 0.000000
data.str : C/C++
data.i : 10
data.f : 1314.520020
data.str : C/C++
在这里,咱们能够看到上面注释 1 共用体的 i 和 f 成员的值有损坏,由于最后赋给变量的值占用了内存位置,这也是 str 成员可以无缺输出的缘由。咱们看注释 2 ,此次咱们在同一时间只使用一个变量成员,因此都能无缺输出。
参考 17.(位域的介绍)
C 语言提供了 typedef 关键字,您可使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE:
typedef unsigned char BYTE;
在这个类型定义以后,标识符 BYTE 可做为类型 unsigned char 的缩写,例如:
BYTE b1, b2;
按照惯例,定义时会大写字母,以便提醒用户类型名称是一个象征性的缩写,但您也可使用小写字母,以下:
typedef unsigned char byte;
您也可使用 typedef 来为用户自定义的数据类型取一个新的名字。例如,您能够对结构体使用 typedef 来定义一个新的数据类型名字,而后使用这个新的数据类型来直接定义结构变量,以下:
typedef struct Books {
char title[50];
char author[50];
char subject[50];
int book_id;
} Book;
#define TRUE 1
#define FALSE 0
void 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);
printf( "TRUE 的值: %d\n", TRUE);
printf( "FALSE 的值: %d\n", FALSE);
}
输出:
书标题 : C 教程
书做者 : Runoob
书类目 : 编程语言
书 ID : 12345
TRUE 的值: 1
FALSE 的值: 0
typedef vs define
define是 C 指令,用于为各类数据类型定义别名,与typedef相似,可是它们有如下几点不一样:
(1)typedef仅限于为类型定义符号名称,#define不只能够为类型定义别名,也能为数值定义别名,好比您能够定义 1 为 ONE。
(2)typedef是由编译器执行解释的,#define语句是由预编译器进行处理的。
例子能够参考上面是 #define 使用。
本节知识将会以分节的形式向你们展现,又想要学习C语言的小伙伴能够关注笔者!一块儿来加油呀~
自学C/C++编程难度很大,不妨和一些志同道合的小伙伴一块儿学习成长!
C语言C++编程学习交流圈子,【点击进入】微信公众号:C语言编程学习基地
有一些源码和资料分享,欢迎转行也学习编程的伙伴,和你们一块儿交流成长会比本身琢磨更快哦!