c语言的作用域、变量与结构体
2014-12-10 22:46
323 查看
一、变量的作用域根据变量的作用域,可以分为:1.局部变量:1>定义:在函数(代码块)内部定义的变量(包括函数的形参)2>作用域:局部变量只有在定义它的函数内部使用,其它函数不能使用它。从定义变量的那一行开始,一直到代码块结束3>生命周期:从定义变量的那一行开始分配存储空间,代码块结束后,就会被回收4>没有固定的初始值2.全局变量1>定义:在函数外面定义的变量2>作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享)3>生命周期:程序一启动就会分配存储空间,程序退出时才会被销毁4>默认的初始值就是0
5.结构体类型不能重复定义
,形参是改变了,但是实参一直没有变过九、指向结构体的指针*每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量*结构体指针变量的定义形式:struct结构体名称*指针变量名*有了指向结构体的指针,那么就有3种访问结构体成员的方式结构体变量名.成员名(*指针变量名).成员名指针变量名->成员名
inta; intmain() { intb; return0; }第1行的变量a是全局变量,第7行的变量b是局部变量。
//全局变量:a、b、c //局部变量:v1、v2、e、f #include<stdio.h> //变量a的初值是10 inta=10; //变量b的初值是0 //变量c的初值是20 intb,c=20; intsum(intv1,intv2) { returnv1+v2; } voidtest() { b++; inti=0; i++; printf("b=%d,i=%d\n",b,i); } intmain() { test(); test(); test(); inte=10; { { intf=30; } } return0; }
二、变量的存储类型
*变量的存储类型就是指变量存储在什么地方。有3个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。变量的存储类型决定了变量何时创建、何时销毁以及它的值能保持多久,也就是决定了变量的生命周期。*C语言根据变量的存储类型的不同,可以把变量分为:自动变量、静态变量、寄存器变量。1.自动变量
1>定义:自动变量是存储在堆栈中的。2>哪些是自动变量:被关键字auto修饰的局部变量都是自动变量,但是极少使用这个关键字,基本上是废的,因为所有的局部变量在默认情况下都是自动变量。2.静态变量1>定义:静态变量是存储在静态内存中的,也就是不属于堆栈。2>哪些是静态变量:所有的全局变量都是静态变量被关键字static修饰的局部变量也是静态变量3>生命周期:静态变量在程序运行之前创建,在程序的整个运行期间始终存在,直到程序结束。3.寄存器变量
1>定义:存储在硬件寄存器中的变量,称为寄存器变量。寄存器变量比存储在内存中的变量访问效率更高(默认情况下,自动变量和静态变量都是放在内存中的)2>哪些变量是寄存器变量:被关键字register修饰的自动变量都是寄存器变量只有自动变量才可以是寄存器变量,全局变量和静态局部变量不行寄存器变量只限于int、char和指针类型变量使用3>生命周期:因为寄存器变量本身就是自动变量,所以函数中的寄存器变量在调用该函数时占用寄存器中存放的值,当函数结束时释放寄存器,变量消失。intmain(){ registerinta; return0; }
第2行的变量a是个寄存器变量。4>使用注意:由于计算机中寄存器数目有限,不能使用太多的寄存器变量。如果寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存3>生命周期:静态变量在程序运行之前创建,在程序的整个运行期间始终存在,直到程序结束。
#include<stdio.h> inta; voidtest(){ staticintb=0; b++; intc=0; c++; printf("b=%d,c=%d\n",b,c); } intmain(){ inti; //连续调用3次test函数 for(i=0;i<3;i++){ test(); } return0; }*第3行的变量a、第6行的变量b都是静态变量,第9行的变量c、第16行的变量i是自动变量。*因为第6行的变量b是静态变量,所以它只会被创建一次,而且生命周期会延续到程序结束。因为它只会创建一次,所以第6行代码只会执行一次,下次再调用test函数时,变量b的值不会被重新初始化为0。*注意:虽然第6行的变量b是静态变量,但是只改变了它的存储类型(即生命周期),并没有改变它的作用域,变量b还是只能在test函数内部使用。*我们在main函数中重复调用test函数3次,输出结果为:
一、什么是结构体
*当一个整体由多个数据构成时,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型的数据。*在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名、年龄、身高等数据构成,这些数据都具有不同的类型,姓名可以是字符串类型,年龄可以是整型,身高可以是浮点型。*结构体允许内部的元素是不同类型的。二、结构体的定义1.定义形式
结构体内部的元素,也就是组成成分,我们一般称为"成员"。结构体的一般定义形式为:struct 结构体名{ 类型名1 成员名1; 类型名2 成员名2; …… 类型名n 成员名n; };例如
structDate { intyear; intmonth; intday; };struct是关键字,是结构体类型的标志。
2.举例
比如,我们定义一个学生structStudent{ char*name;//姓名 intage;//年龄 floatheight;//身高 };上面定义了一个叫做Student的结构体,共有name、age、height3个成员。三、结构体变量的定义前面只是定义了名字为Student的结构体类型,并非定义了一个结构体变量,就像int一样,只是一种类型。接下来定义一个结构体变量,方式有好多种。
1.先定义结构体类型,再定义变量
1structStudent{ 2char*name; 3intage; 4}; 5 6structStudentstu;
第6行定义了一个结构体变量,变量名为stu。struct和Student是连着使用的。
2.定义结构体类型的同时定义变量
structStudent{ char*name; intage; }stu;结构体变量名为stu
3.直接定义结构体类型变量,省略类型名
struct{ char*name; intage; }stu;结构体变量名为stu
/* 数组:只能由多个相同类型的数据构成 结构体:可以由多个不同类型的数据构成 */ #include<stdio.h> intmain() { //intages[3]={[2]=10,11,27}; //intages[3]={10,11,29}; //1.定义结构体类型 structPerson {//里面的3个变量,可以称为是结构体的成员或者属性 intage;//年龄 doubleheight;//身高 char*name;//姓名 }; //2.根据结构体类型,定义结构体变量 structPersonp={20,1.55,"jack"}; p.age=30; p.name="rose"; printf("age=%d,name=%s,height=%f\n",p.age,p.name,p.height); /*错误写法 structPersonp2; p2={30,1.67,"jake"}; */ structPersonp2={.height=1.78,.name="jim",.age=30}; //p2.age=25; return0; }四、结构体的注意点
1.不允许对结构体本身递归定义
如下做法是错误的,注意第3行structStudent{ intage; structStudentstu; };
2.结构体内可以包含别的结构体
#include<stdio.h>intmain()
{
structDate { intyear; intmonth; intday; };//类型
structStudent
{
intno;//学号structDatebirthday;//生日structDateruxueDate;//入学日期//这种写法是错误的
//structStudentstu;
};structStudentstu={1,{2000,9,10},{2012,9,10}};printf("year=%d,month=%d,day=%d\n",stu.birthday.year,stu.birthday.month,stu.birthday.day);printf("year=%d,month=%d,day=%d\n",stu.ruxueDate.year,stu.ruxueDate.month,stu.ruxueDate.day);return0;
}
3.定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为int类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量
structStudent{ char*name; intage; }; structStudentstu;
第1~4行并没有分配存储空间,当执行到第6行时,系统才会分配存储空间给stu变量。
4.结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列
比如下面的Student结构体:structStudent{ char*name;//姓名 intage;//年龄 floatheight;//身高 };
在16位编译器环境下,一个Student变量共占用内存:2+2+4=8字节。
5.结构体类型不能重复定义
structStudent { intage; }; structStudent { doubleheight; }; structStudentstu;五、结构体的初始化将各成员的初值,按顺序地放在一对大括号{}中,并用逗号分隔,一一对应赋值。比如初始化Student结构体变量stu
structStudent{ char*name; intage; }; structStudentstu={"xiaomeng",27};只能在定义变量的同时进行初始化赋值,初始化赋值和变量的定义不能分开,下面的做法是错误的:
structStudentstu; stu={"MJ",27};六、结构体的使用
1.一般对结构体变量的操作是以成员为单位进行的,引用的一般形式为:结构体变量名.成员名
structStudent{ char*name; intage; }; structStudentstu; //访问stu的age成员 stu.age=27;第8行对结构体的age成员进行了赋值。"."称为成员运算符,它在所有运算符中优先级最高
2.如果某个成员也是结构体变量,可以连续使用成员运算符"."访问最低一级成员
structDate{ intyear; intmonth; intday; }; structStudent{ char*name; structDatebirthday; }; structStudentstu; stu.birthday.year=1986; stu.birthday.month=9; stu.birthday.day=10;
注意第14行以后的代码
3.相同类型的结构体变量之间可以进行整体赋值
structStudent{ char*name; intage; }; structStudentstu1={"MJ",27}; //将stu1直接赋值给stu2 structStudentstu2=stu1; printf("ageis%d",stu2.age);
注意第9行。输出结果为:
补齐算法
#include<stdio.h>七、结构体数组
intmain()
{
structStudent
{//补齐算法
intage;//4个字节chara;//1个字节//char*name;//8个字节
};structStudentstu;
//stu.age=20;
//stu.name="jack";
//补齐算法(对齐算法)
//结构体所占用的存储空间必须是最大成员字节数的倍数ints=sizeof(stu);
printf("%d\n",s);return0;
}
1.定义
跟结构体变量一样,结构体数组也有3种定义方式structStudent{ char*name; intage; }; structStudentstu[5];//定义1
structStudent{ char*name; intage; }stu[5];//定义2
struct{ char*name; intage; }stu[5];//定义3上面3种方式,都是定义了一个变量名为stu的结构体数组,数组元素个数是5
2.初始化
struct{ char*name; intage; }stu[2]={{"MJ",27},{"JJ",30}};也可以用数组下标访问每一个结构体元素,跟普通数组的用法是一样的举例
#include<stdio.h>八、结构体作为函数参数将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参。
intmain()
{
structRankRecord
{
intno;//序号4
char*name;//名称8
intscore;//积分4
};//intages[3]={10,19,29};//intages[3];
//对齐算法
//能存放3个结构体变量,每个结构体变量占16个字节
//72
structRankRecordrecords[3]=
{
{1,"jack",5000},{2,"jim",500},{3,"jake",300}
};records[0].no=4;
//错误写法
//records[0]={4,"rose",9000};for(inti=0;i<3;i++)
{
printf("%d\t%s\t%d\n",records[i].no,records[i].name,records[i].score);
}//printf("%d\n",sizeof(records));return0;
}
#include<stdio.h>//定义一个结构体*首先在第4行定义了一个结构体类型Student*在第18行定义了一个结构体变量stu,并在第22行将其作为实参传入到test函数输出结果为:
structStudent{
intage;
};voidtest(structStudentstu){
printf("修改前的形参:%d\n",stu.age);
//修改实参中的age
stu.age=10;printf("修改后的形参:%d\n",stu.age);
}intmain(intargc,constchar*argv[]){structStudentstu={30};
printf("修改前的实参:%d\n",stu.age);//调用test函数
test(stu);printf("修改后的实参:%d\n",stu.age);
return0;
}
,形参是改变了,但是实参一直没有变过九、指向结构体的指针*每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量*结构体指针变量的定义形式:struct结构体名称*指针变量名*有了指向结构体的指针,那么就有3种访问结构体成员的方式结构体变量名.成员名(*指针变量名).成员名指针变量名->成员名
#include<stdio.h>输出结果:age=30,no=1 age=30,no=1 age=30,no=1
intmain()
{
structStudent
{
intno;
intage;
};
//结构体变量
structStudentstu={1,20};//指针变量p将来指向structStudent类型的数据
structStudent*p;//指针变量p指向了stu变量
p=&stu;p->age=30;//第一种方式
printf("age=%d,no=%d\n",stu.age,stu.no);//第二种方式
printf("age=%d,no=%d\n",(*p).age,(*p).no);//第三种方式
printf("age=%d,no=%d\n",p->age,p->no);return0;
}
相关文章推荐
- C语言变量的作用域和存储类型
- 【Notes】结构变量中的作用域
- C语言用static限制函数以及全局变量的作用域
- C语言中变量的作用域 .
- C语言变量、函数的作用域及变量的存储方式
- C语言学习第十二讲-变量作用域
- C06_C语言-变量作用域
- C语言之变量的作用域及存储方式
- C语言学习笔记【函数】函数调用与变量的作用域
- C语言的变量作用域
- C语言struct结构类型定义和结构变量说明
- C语言中变量的作用域
- C语言变量作用域、生存期及static问题
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- C语言的变量的作用域和生存期
- C语言的变量作用域及头文件
- 关于c语言中变量的作用域
- C语言中变量的作用域
- C语言中变量的作用域
- 华为C语言编程规范(6)—变量、结构