1:修饰普通变量,代表只读的意思
const int a=100;//定义了一个只读变量a的值为100
以后在程序中,不能给a赋值了
a=20;//错误的,a只读
例子:
#include
int main(int argc,char *argv[])
{
const int a=100;
a=200;
printf("%d\n",a);
return 0;
}
gcc编译的结果如下
gec@ubuntu:/mnt/hgfs/share/C语言/day11(8.29)/code$ gcc demo.c
demo.c: In function ‘main’:
demo.c:5:2: error: assignment of read-only variable ‘a’(报错,只读,不能修改)
2:const 修饰指针
(1)const char *str;
意思是str指向的内存的内容不能通过str来修改
用来保护str所指向的内容
(2)char *const str;
意思是str是只读的变量,str不能指向别的地方
(3)const char *const str;
str不能指向别的地方,指向的内存的内容也不能通过str去修改
(4)例子1:const char *str;即指向可以改,指向的内容不可以改
#include
#include
int main(int argc,char *argv[])
{
char buf[20]="hello world";
const char* str=buf;
strcpy(str,"hellokitty"); //错误
str="hellokitty";//正确
printf("buf=%s\n",buf);
return 0;
}
//(1)第一种情况
//没有加const修饰,使用strcpy是以修改buf数组里面的内容
//gec@ubuntu:/mnt/hgfs/share/C语言/day11(8.29)/code$ ./a.out
//buf=hellokitty
//(2)第二种情况
//有加const修饰,编译结果如下:
(5)例子2:char *const str;即指向不能改变,指向的内容可修改
#include
#include
int main(int argc,char *argv[])
{
char buf[20]="hello world";
char* const str=buf;
//strcpy(str,"hellokitty"); //正确
//*str='w'; //正确
//str="hellokitty"; //错误
printf("buf=%s\n",buf);
return 0;
}
(6)例3:const char *const str;即指向不能改,指向的内容也不能改
#include
#include
int main(int argc,char *argv[])
{
char buf[20]="hello world";
const char* const str=buf;
//strcpy(str,"hellokitty");//错误
//*str='w'; //错误
str="hellokitty";//错误
printf("buf=%s\n",buf);
return 0;
}
(1)结构体的概念
在程序开发的时候,需要将不同类型的数据组合成一个有机的整体,以便于引用。如:
一个的学生的学号、姓名、性别、年龄、住址
int num;
char name[20];
char sex;
int age;
char addr[30];
显然单独定义以上变量比较繁琐,数据不便于管理,所以c语言发明了结构体类型
结构体是一种构造数据类型
前面学过一种构造类型------->数组
构造类型:
不是基本类型的数据结构也不是指针类型,它是若干个相同或者不同类型的数据构成的集合。
数组:描述一组具有相同类型数据的有序集合用于处理大量相同类型的数据运算
结构体:一种或者多种基本类型或构造类型的数据的集合
(2)结构体类型的定义
定义方法:
我们在使用结构体之前必须先有类型,再用类型定义数据结构
这个类型相当于一个模具
1)先定义结构体类型,再定义结构体变量
struct 结构体类型名{
成员列表
};
例子:
struct stu{
int num;
char name[20];
char sex;
};
//有了结构体类型后,就可以利用类型定义变量
struct stu liming,lucy,bob;//定义了三个struct stu类型的变量
每个变量都有三个成员,分别是num,name,sex
2)在定义结构体类型的时候顺便定义结构体变量,后面如果还想定义变量是可以的
struct 结构体类型名{
成员列表
}变量1,变量2;
struct 结构体类型名 变量3,变量4;
struct stu{
int num;
char name[20];
char sex;
}liming,lucy,bob;
struct stu xiaoming,limei;
3)在定义结构体类型的时候,没有结构体类型名,顺便定义结构体变量,因为没有类型名,所以以后不能再定义相关类型的数据
struct {
成员列表;
}变量1,变量2;
struct {
int num;
char name[20];
char sex;
}liming,lucy,bob;
以后就没有办法再定义这个结构体类型的数据了,因为没有类型名
4)最常用的方法
通常将一个结构体类型重新取一个类型名,用新的类型名替代原先的类型
步骤1:先用结构体类型定义变量
struct stu{
int num;
char name[20];
char sex;
}bob;
步骤2:新的类型名替代变量名
struct stu{
int num;
char name[20];
char sex;
}STU;
步骤3:在最前加typedef
typedef struct stu{
int num;
char name[20];
char sex;
}STU;
步骤1和2是在草稿纸上做的,步骤3才是我们想要的
综上:以后STU就相当于struct stu;
STU bob 等价于struct stu bob;
1、结构体定义和初始化
结构体变量是一个变量,这个变量是由若干个相同或者不同数据构成的集合
(1)必须先有结构体类型,再定义变量
(2)再定义变量的时候,顺便赋值,称为结构体的初始化
(3)结构体初始化,各个成员按顺序初始化
例子1:
//定义结构体类型
struct stu
{
int num;
char name[20];
char sex;
};
int main(int argc,char *argv[])
{
//定义变量并进行初始化
struct stu boy={
50,
"xiaoming",
'm'
};
return 0;
}
2、结构体变量的使用
定义了结构体变量,使用结构体变量
(1)结构体变量成员的引用方法
结构体变量.成员名
例子1:
//定义结构体类型
struct stu
{
int num;
char name[20];
char sex;
};
int main(int argc,char *argv[])
{
//定义变量并进行初始化
struct stu boy;
boy.num=100;
printf("boy.num=%d\n",boy.num);
return 0;
}
例子2:
struct stu
{
int num;
char name[20];
char sex;
char *addr;
};
int main(int argc,char *argv[])
{
//定义变量并进行初始化
struct stu boy;
boy.num=100;
//boy.name="lilei";//错误写法,因为boy.num是数组的名字,是个常量,不能给常量赋值
strcpy(boy.name,"lilei");
//strcpy(boy.addr,"beijing");//错误写法,boy.addr是个野指针
boy.addr="beijing";
printf("boy.num=%d\n",boy.num);
printf("boy.name=%s\n",boy.name);
printf("boy.addr=%s\n",boy.addr);
return 0;
}
(2)结构体成员的多级引用(看例题代码)
例子1:
struct date
{
int year;
int month;
int day;
};
struct stu
{
int num;
char name[20];
char sex;
struct date birthday;
};
int main(int argc,char *argv[])
{
//定义变量并进行初始化
struct stu boy={
100,
"lilei",
'm'
};
boy.birthday.year=2000;
boy.birthday.month=1;
boy.birthday.day=1;
printf("%d %s %c\n",boy.num,boy.name,boy.sex);
printf("%d %d %d\n",boy.birthday.year,boy.birthday.month,boy.birthday.day);
return 0;
}
(3)相同类型的变量可以相互赋值
注意:必须是相同类型的结构体变量,才能相互赋值
例子:
struct stu
{
int num;
char name[20];
char sex;
};
struct stu2
{
int num;
char name[20];
char sex;
float score;
};
int main(int argc,char *argv[])
{
//定义变量并进行初始化
struct stu boy={
100,
"lilei",
'm'
};
//struct stu2 boy2;不能正确赋值
struct stu boy2;//能正确的赋值
boy2=boy;//只能给相同类型的结构体变量赋值
printf("%d %s %c\n",boy2.num,boy2.name,boy2.sex);
return 0;
}
结构体数组是一个数组,由若干个相同类型的结构体变量构成的集合
1.结构体数组的定义方法
struct 结构体类型名 数组名[元素个数];
例子:
struct stu{
int num;
char name[20];
char sex;
};
struct stu edu[3];//定义了一个struct stu类型的结构体数组edu
这个数组有三个元素分别是edu[0]、edu[1]、edu[2]
2、结构体数组元素的引用 数组名[下标]
3、数组元素的使用
edu[0].num=101;//用101给edu数组的第0个结构体变量的num赋值
strcpy(edu[1].name,”lilei”);
例子:
//定义结构体类型
typedef struct student
{
int num;
char name[20];
float score;
}STU;
int main(int argc,char *argv[])
{
//定义变量并进行初始化
STU edu[3]={
{1001,"lilei",89},
{1002,"lucy",90},
{1003,"bob",100}
};
float sum=0;
int i;
for(i=0;i<3;i++)
{
sum=sum+edu[i].score;
}
printf("平均成绩为:%f\n",(float)sum/3);
return 0;
}
即结构体的地址,结构体变量存放在内存中,也有起始地址
我们定义一个变量去存放这个地址,那么这个变量就是结构体指针变量
结构体指针变量也是个指针,同样在32位系统中占4个字节,存放一个地址编号
1.结构体指针变量的定义
struct 结构体类型名 * 结构体指针变量名;
struct stu{
int num;
char name[20];
};
struct stu *p;//定义了一个struct stu*类型的指针变量
变量名是p,p占4个字节,用来保存结构体变量的地址编号
struct stu boy;
p=&boy;
访问结构体变量的成员方法:
例子:
(1)boy.num=100;//可以的,通过结构体变量名.成员名
(2)(*p).num=100;//可以的,*p相当于p指向的变量boy
(3)p->num=100;可以的,指针->成员名
注意:通过结构体指针来引用指针指向的结构体的成员,前提是指针必须先指向一个结构体变量
例子:
struct stu
{
int num;
char name[20];
};
int main(int argc,char *argv[])
{
struct stu boy={100,"lilei"};
struct stu *p;
p=&boy;
printf("boy.num=%d\n",boy.num);
printf("(*p).num=%d\n",(*p).num);
printf("p->num=%d\n",p->num);
return 0;
}
结构体指针取得应用场景:
(1)保存结构体变量的地址
例子:
#include
#include
//定义结构体类型
typedef struct stu
{
int num;
char name[20];
}STU;
int main(int argc,char *argv[])
{
STU *p,lucy;
p=&lucy;// 保存结构体变量的地址
p->num=100;
printf("p->num=%d\n",p->num);
return 0;
}
(2)传结构体变量的地址
例子:
//定义结构体类型
typedef struct stu
{
int num;
char name[20];
float score;
}STU;
void fun(STU *p)
{
p->num=100;
(*p).score=88.8f;
strcpy(p->name,"lucy");
}
int main(int argc,char *argv[])
{
STU boy;
fun(&boy);//传结构体变量的地址
printf("%d %s %f\n",boy.num,boy.name,boy.score);
return 0;
}
(3)传结构体数组的地址
结构体数组,多个相同类型的结构体变量构成的,存放在内存中,也有起始地址,就是第0个结构体的地址
例子:
typedef struct stu
{
int num;
char name[20];
float score;
}STU;
void fun(STU *p)
{
p[1].num=100;
(*(p+1)).score=90.0f;
strcpy((p+1)->name,"lucy");
}
int main(int argc,char *argv[])
{
STU edu[3];
fun(edu);//传结构体数组的地址
printf("%d %s %f\n",edu[1].num,edu[1].name,edu[1].score);
return 0;
}
注意:
(1)结构体变量的地址编号和结构体成员第一个成员的地址编号相同,但指针类型不同
例子:
typedef struct stu
{
int num;
char name[20];
float score;
}STU;
int main(int argc,char *argv[])
{
STU lucy;
printf("%p\n",&lucy);//STU *
printf("%p\n",&(lucy.num));//int *
return 0;
}
(2)结构体数组的地址就是结构体数组中第0个元素的地址
例子:
typedef struct stu
{
int num;
char name[20];
float score;
}STU;
int main(int argc,char *argv[])
{
STU edu[3];
//结构体数组的地址就是结构体数组中第0个元素的地址
printf("edu=%p\n",edu);//STU *
printf("&deu[0]=%p\n",&edu[0]);//STU *
//结构体变量的地址编号和结构体成员第一个成员的地址编号相同
printf("&deu[0].num=%p\n",&edu[0].num);//int *
return 0;
}