标签:
1.【掌握】返回指针的函数
2.【掌握】指向函数的指针
3.【掌握】结构体的声明
4.【掌握】结构体与数组
5.【掌握】结构体与指针
6.【掌握】结构体的嵌套
7.【掌握】结构体与函数
指针作为函数的返回值
指针是可以作为函数的返回值的,不能返回局部变量的指针,因为当函数执行结束后指针变量就释放了。如果我们真的需要返回一个指针变量,那就要保证我 们的函数执行完毕之后,指针指向的变量仍然存储在内存之中。那我们可以将变量创建在堆空间中,使用malloc或者calloc申请空间。或者直接声明为 全局变量或者用static修饰的局部变量。
如果函数需要返回一个字符串,我们可以返回(char *)类型字符串,不要使用字符数组,因为字符数组在函数执行结束后,就释放了。而使用(char *)声明的字符串是存储在数据段的,直到程序执行结束才会释放。
1
2
3
4
5
6
7
8
9
10
|
#include <stdio.h>
#include <stdlib.h>
char*getWeekDay(intday){
return"星期N";//返回的是字符串在数据段(常量区)中的地址
}
intmain(){
char*weekDay=getWeekDay(2);
return0;
}
|
程序在运行的时候,函数是存储在内存(代码段)之中的,存储函数的空间肯定也是有地址的,所以我们可以用指针指向函数。
语法:返回值类型 (*指针名)([参数列表]);
注意:
1.函数的地址就是函数名。
2.指向函数的指针变量,本质上还是一个变量,那么我们就可以声明、赋值给另外一个同类型的指针变量使用。
无参无返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
voidtestFunction(){
printf("这是一个无参无返回值的函数\n");
}
intmain(intargc,constchar*argv[]){
//指针指向函数
void(*pFunction)()=testFunction;//存储没有返回值没有参数的地址,函数名就是函数的地址
//指针调用函数
(*pFunction)();
pFunction();//简写
return0;
}
|
有参有返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include <stdio.h>
intgetSum(intnum1,intnum2){
returnnum1+num2;
}
intmain(intargc,constchar*argv[]){
//指针指向函数,参数列表可以省略
int(*pFunction)()=getSum;
//指针调用函数
intsum=pFunction(10,12);
printf("sum = %d\n",sum);
return0;
}
|
应用场景:多种方式对字符串数组进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#include <stdio.h>
#include <string.h>
/**
* 对字符串进行各种排序
*
* @param countries 需要被排序的字符串数组
* @param length 字符串数组的长度
* @param pCompare 指向控制排序方式的函数指针
*/
voidsort(char*countries[],intlength,int(*pCompare)()){
for(inti=0;i<length;i++){
for(intj=0;j<length-1-i;j++){
//调用比较字符串的函数进行比较
intres=pCompare(countries[j],countries[j+1]);
if(res>0){
//交换位置
char*temp=countries[j];
countries[j]=countries[j+1];
countries[j+1]=temp;
}
}
}
}
/**
* 比较字符串大小
*
* @param str1 第一个字符串
* @param str2 第二个字符串
*
* @return 第一个大字符串大返回正数,第二个字符串大返回负数,相同返回0
*/
intcompare(char*str1,char*str2){
return(int)strcmp(str1,str2);
}
/**
* 比较字符串的长度
*
* @param str1 第一个字符串
* @param str2 第二个字符串
*
* @return 第一个字符串大返回1,第二个字符串大返回-1,相同返回0
*/
intcompare1(char*str1,char*str2){
unsignedlonglen1=strlen(str1);
unsignedlonglen2=strlen(str2);
if(len1>len2){
return1;
}elseif(len1<len2){
return-1;
}
return0;
}
intmain(intargc,constchar*argv[]){
char*countries[]={
"fldjfljfaf",
"fdahfiyyyyfh",
"aadjflui",
"jabfaf"
};
//计算字符串数组长度
intlength=sizeof(countries)/sizeof(char*);
//传入字符串数组,数组长度,指向函数的指针。按字符串大小排序
sort(countries,length,compare);
//传入字符串数组,数组长度,指向函数的指针。按字符串长度排序
sort(countries,length,compare1);
//遍历打印字符串
for(inti=0;i<length;i++){
printf("%s\n",countries[i]);
}
return0;
}
|
在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生信息这个整体可以由姓名、年龄、身高等数据构成,这些数据都具有不同的数据类 型,姓名可以是字符指针类型,年龄可以是整型,身高可以是浮点型。C语言提供了一种构造类型来解决这个问题,由程序员自己声明多个数据类型组成一个整体当 做一种新的数据类型,这个玩意就是结构体。结构体里的声明的多个数据类型变量叫做结构体的成员。
声明结构体类型语法:
struct 类型名 {
数据类型1 成员名1;
数据类型2 成员名2;
..........
};
声明结构体变量语法:struct 类型名 变量名;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//声明类型的同时声明变量
structStudent{
char*name;
intage;
floatheigth;
}stu,stu1;//可以同时声明多个变量
//匿名结构体。声明类型的同时声明变量,可以省略类型名,但是这种方法不能再次声明新的变量了
struct{
char*name;
intage;
floatheigth;
}stu,stu1;//也可以同时声明多个变量
//声明类型,再声明变量
structStudent{
char*name;
intage;
floatheigth;
};
structStudentstu1,stu2;//变量名是stu1,stu2.可以同时声明多个变量
structStudentstu2;//变量名是stu3
|
为结构体变量中的成员赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <stdio.h>
intmain(intargc,constchar*argv[]){
//声明一个结构体Student1
structStudent1{
char*name;
intage;
floatheigth;
};
structStudentstu1;
stu1.name="zhoujianfeng";//单独为变量的每个成员赋值
stu1.age=18;
stu1.heigth=1.9f;
//声明一个结构体Student2
structStudent2{
char*name;
intage;
floatheigth;
};
structStudentstu2={"zhoujianfeng",18,1.9f};//声明变量的同时初始化
structStudentstu3={"zhoujianfeng",18};//初始化部分
structStudentstu4={.age=18};//指定成员初始化
structStudentstu5=stu2;//将stu2赋值给stu5
return0;
}
|
使用结构体注意:
1.这个新声明的结构体也是一个数据类型,由程序员自己声明的新类型,所以可以声明这个结构体类型的变量。
2.定义在大括号之中的变量,叫新类型的成员。必须要先声明结构体类型,再声明结构体变量。
3.结构体类型名首字母大写,并且结构体末尾需要加分号,
4.声明一个结构体变量没有初始化,成员的值是垃圾值,如果声明的同时初始化了部分,其他成员初始化为0。
5.相同类型的结构体变量是可以相互赋值的,赋值是将原结构体中的每一个成员的值挨个拷贝给目标结构体变量。
6.结构体变量名,直接代表整个结构体变量。在外面学习到的所有数据类型中,只有数组名、函数名才代表他们的地址。其他都是代表变量本身
语法:struct 结构体类型名 数组名[长度];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#include <stdio.h>
intmain(intargc,constchar*argv[]){
structStudent{
char*name;
intage;
intscore;
};
//stuArray数组的每一个元素的类型是一个struct Student结构体类型
structStudentstuArray[]={
{"小明",19,99},
{"小芳",19,99},
{"小东",18,20}
};
//单独初始化一个元素,需要做类型强转,不然编译器不知道赋值给数组还是结构体
stuArray[0]=(structStudent){"小明",19,100};
//数组长度 = 数组占的总字节数 / 每个元素占的字节数
intlength=sizeof(stuArray)/sizeof(structStudent);
//遍历数组,打印3个学生的信息
for(inti=0;i<length;i++){
printf("%s %d %d\n",stuArray[i].name,stuArray[i].age,stuArray[i].score);
}
return0;
}
|
结构体变量也是一个变量,那么这个结构体变量一定是有内存地址的,所以我们就可以搞个指针指向这个结构体变量。然后我们就可以通过指针间接操作结构体变量。
语法:struct 结构体类型名 *指针名;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#include <stdio.h>
structStudent{
char*name;
intage;
intscore;
};
intmain(intargc,constchar*argv[]){
//初始化变量
structStudentstu={"静静",19,100};
//p指针指向stu变量
structStudent*p=&stu;
//第一种方式
(*p).name="芳芳";
(*p).age=18;
(*p).score=99;
//第二种方式
p->name="东东";
p->age=18;
p->score=99;
printf("%s %d %d\n",p->name,p->age,p->score);
return0;
}
|
我们在为结构体写成员的时候,发现某个成员也是一个需要多个数据组成一个整体的数据,这个时候我们就可以使用结构体嵌套。在结构体内声明另一个结构体类型的变量作为成员来使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <stdio.h>
//日期结构体类型
structDate{
intyear;
intmonth;
intday;
};
//人结构体类型
structPerson{
char*name;
intage;
structDatebirthday;
};
intmain(intargc,constchar*argv[]){
//创建一个人并赋值
structPersonzhouJianFeng={"周剑峰",23,{2015,9,18}};
// struct Person zhouJianFeng = {"周剑峰",23,2015,9,18};//可以成员的省略大括号
//打印出这个人的信息
printf("姓名:%s\n年龄:%d\n生日:%d年%d月%d日\n",zhouJianFeng.name,zhouJianFeng.age,zhouJianFeng.birthday.year,zhouJianFeng.birthday.month,zhouJianFeng.birthday.day);
return0;
}
|
结构体作为函数的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <stdio.h>
//人结构体类型
structPerson{
char*name;
intage;
};
voidtest(structPerson*stu){
stu->name="周剑峰";
stu->age=18;
}
intmain(){
structPersonzhou={"静静",19};
test(&zhou);//调用函数,传入地址
printf("%s %d\n",zhou.name,zhou.age);
return0;
}
|
结构体作为函数的返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <stdio.h>
//人结构体类型
structPerson{
char*name;
intage;
};
structPersongetStu(){
structPersonstu={"静静",19};
returnstu;//是返回一个变量的值
}
intmain(){
structPersonstu=getStu();
printf("%s %d\n",stu.name,stu.age);
return0;
}
|
标签:
原文地址:http://www.cnblogs.com/liehuntianshi/p/4862391.html