本地(局部)变量和全局变量
一、本地变量:又称局部变量
① 定义: 函数的每次运行,就产生一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的。
② 特点:
本地变量不会被默认初始化;
本地变量可以定义在函数或语句的块内;
块内定义了和外面同名的变量会掩盖外面的。
二、全局变量:
① 定义: 定义在函数外面的变量。
② 特点:
没有做初始化的全局变量会得到0值,指针会得NULL值;
全局变量与任何函数都无关;
在任何函数内部都可以使用它们;
如果函数内部存在与全局变量同名的变量,则全局变量被掩盖。
结构在函数内、外?
和本地变量一样,在函数内部声明的结构类型只能在函数内部使用,所以通常在函数外部声明结构类型,这样就可以被多个函数所使用。
声明结构的形式
① 先定义结构体,再定义变量
//上面声明结构,下面定义变量
//struct是关键字,声明一个结构类型叫point
struct point{//大括号里的是这个结构里的成员
int x;
int y;
};
struct point p1,p2;//定义两个变量叫p1和p2,类型是struct point,p1和p2都是point里面有x和y的值
② 定义匿名结构体直接带变量
//struct是关键字,声明一个没有名字的结构类型
struct{//大括号里的是这个结构里的成员
int x;
int y;
}p1,p2;//定义两个没有类型名字的变量p1和p2,p1和p2都是无名结构,里面有x和y的值
③ 定义结构体直接带变量
//struct是关键字,声明一个结构类型叫point
struct point{//大括号里的是这个结构里的成员
int x;
int y;
}p1,p2;//定义两个变量叫p1和p2,类型是struct point,p1和p2都是point里面有x和y的值
对于第一和第三种形式,都声明了结构point;
对于第二种形式没有声明point,只是定义了两个变量。
结构变量和结构成员
struct point p1;//定义结构变量p1
p1.x=6;//访问结构成员,注意.的左边一定是结构变量
数组用 [] 运算符和下标访问其成员,eg:a[0]=10;
结构用 . 运算符和名字访问其成员,eg:p1.x; 和 p2.y;
结构的初始化
struct point{
int x;
int y;
}p1,p2;
int main{
//定义这种结构类型的结构变量demo
struct point demo={20,22};//赋值x=20,y=22,大括号里面的值依次赋给结构体中的成员
//或
struct point demo={.x=20,.y=22};//赋值x=20,y=22,指定成员赋值,若没有赋值则默认为0
};
结构运算
要访问整个结构,直接用结构变量的名字
p1=(struct point){5,10};
//相当于p1.x=5;p1.y=10
对于整个结构,可以做赋值、取地址,也可以传递给函数参数
p1=p2;//相当于pl.x=p2.x;pl.y=p2.y;
结构指针
数组的变量名字就是数组的地址,和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符
struct point demo;
struct point *pdemo=&demo;
结构作为函数参数
int test(struct demo d);
整个结构可以作为参数的值传入函数;
这时候是在函数内新建一个结构变量, 并复制调用者的结构的值;
也可以作为一个返回类型,返回一个结构。
C语言在函数调用时永远是传值的。
指向结构的指针->
用->表示指针所指的结构变量中的成员
struct point{
int x;
int y;
}demo;
struct point *p=&demo;
(*p).x=20;
//同
p->month=20;
结构数组
struct point{
int x;
int y;
}demo;
struct point demo[100];
struct point demo[]={{1,2},{3,4}};
//表示demo[0].x=1,demo[0].y=2;demo[1].x=3,demo[1].y=4
结构中的结构
struct point{
int x;
int y;
};
struct rectangle{
struct point pt1;
struct point pt2;
};
//如果有变量:
struct rectangle r;
//就可以有:
r.pt1.x、r.pt1.y
r.pt2.x、r.pt2.y
//如果有变量定义:
struct rectangle r,*rp;
rp=&r;
//则下面四种形式等价:
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
//注意没有下面这种,因为pt1不是指针
rp->pt1->x
自定义数据类型typedef
C语言提供了 一个叫做typedef的功能来声明一个已有的数据类型的新名字。比如:
typedef int Length;//使得Length成为int类型的别名。
Length a; 等于 int a;
Length a, b,len;
Length numbers[10];
//这样,Length 这个名字就可以代替int出现在变量定义和参数声明的地方了
typedef
声明新的类型的名字,新的名字是某种类型的别名,改善了程序的可读性,新名字的含义更清晰,具有可移植性。
typedef long int64_t;//重载已有的类型名字,新名字的含义更清晰,具有可移植性
typedef struct point{
int x;
int y;
int z;
}demo;//简化了复杂的名字,声明新的类型的名字demo
int64_t i=1000000000000;
demo d=(20,22,11};
typedef long int64_t;//int64_t等价于long
//demo等价于typedef和别名demo中间的所有东西:
typedef struct point{
int x;
int y;
int z;
}demo;
typedef struct point demo;//这样用demo就可以代替struct point
typedef struct node{
int data;
struct node *next;
}aNode;
typedef *char[10] Strings;//Strings是10个字符串的数组类型
联合union
存储:
所有的成员共享一个空间,同一时间只有一个成员是有效的。
union的大小是其最大的成员:sizeof(union…)=sizeof(每个成员)的最大值
初始化:
对第一个成员做初始化
union point{
int a;
int b;
}demo1,demo2;
demo1.a=1;
demo1.b='c';
demo2.1=6;