变量|ios学习之旅------玩转结构体
1.全局变量和局部变量
局部变量:
概念:定义函数内部变量
定义格式:变量类型 变量名称;
作用域:从定义那一行开始到所在代码块结束
生命周期:从代码执行到定义的哪一行开始,到其所在的代码的结束为止
特点:相同的代码块中不可以有同名的变量
不同的代码块中可以有同名的变量,内部的变量会覆盖外部定义的变量
全局变量:
概念:定义在函数外部变量
定义:变量类型 变量名称 = 值;
声明:变量类型 变量名称;
特点:1、不可以重复定义,但可以重复声明
2、局部变量可以与全局变量同名,在局部变量的作用域范围内,那么局部变量会覆盖全局变量
3、如果没有定义仅有声明,系统自动给它定义并将其初始化为0
作用域:从定义的那一行开始,直到文件结束
生命周期:从程序启动开始,直到程序退出才消亡
#include
int num;
//声明
int main(int argc, const char * argv[]) {
printf("num = %d\n",num);
int num = 20;
printf("num = %d\n",num);
{
num = 40;
int num = 10;
printf("num = %d\n",num);
num = 30;
}
printf("num = %d\n",num);
return 0;
}
2.结构体
构造类型:由已有的数据类型构成类型
1、数组:多个同种类型的数据构成的那么一种类型
特点:只能存放一种数类型
2、结构体:从来存放表示某种特定含义的一组数据
它是对数据封装
函数对功能封装
好处:提高代码的可读性
提高数据易用性
提高代码可维护性
定义结构体:
1、定义结构类型
struct 结构类型名称{
成员类型 成员名称;
...
}; //必须加分号
2、通过结构体类型定义结构变量
struct 结构类型名称 结构体变量名称;
#include
int main(int argc, const char * argv[]) {//int scores[] = {59,60};
//int年龄姓名 char *性别 char身高 double体重 double
//int age;
//char sex;
//double height;
//double weight;
//char *name;
//
//int ages[50];
//char sex[50];
//....
//定义一个人结构体类型
struct Person{
int age;
char sex;
double height;
double weight;
char *name;
};
//int num;
//int * pointer;
//定义结构体变量
struct Person person;
//访问结构体成员
person.age = 10;
person.sex = 'M';
person.weight = 20.2;
person.height = 1.2;
person.name = "小明";
printf("age = %d,sex = %c,weight = %.2lf,height = %.2lf,name = %s\n",person.age,person.sex,person.weight,person.height,person.name);
return 0;
}
文章图片
3.定义结构体的多种类型
#include
/*
第一种方式
1、先定义结构体类型
2、定义结构变量
*/
void test()
{struct Person{
int age;
double height;
};
struct Person p1;
}/*
第二种方式
定义结构体类型的同时定义结构变量
*/
void test1()
{
struct Person{
int age;
double height;
} p1,p2 = {20,1.75};
p1 =(struct Person){10,1.2};
printf("age = %d,height = %.2lf\n",p1.age,p1.height);
printf("age = %d,height = %.2lf\n",p2.age,p2.height);
//结构体类型定义是不可以重名的
//struct Person{
//int age;
//double height;
//} p3,p4 = {20,1.75};
}
/*
第三种方式
定义匿名的结构类型的同时定义结构体变量
*/
int main(int argc, const char * argv[]) {
struct{
int age;
char sex;
} p1,p2 = {20,'M'};
p1.age = 10;
p1.sex = 'W';
printf("age = %d,sex = %c\n",p1.age,p1.sex);
p1 = p2;
printf("age = %d,sex = %c\n",p1.age,p1.sex);
//
//p1 = (struct) {10,'w'};
//1、不支持整体赋值
//2、结构体类型不能重复使用
struct{
int age;
char sex;
} p3,p4 = {20,'M'};
return 0;
}
4.结构体作用域
在函数内部,结构类型作用域就如同局部变量一样
在外边定义的结构体类型像全局变量的作用域
作用域:从定义的那一行开始直到文件的结束
注意点:结构类型不能声明
结构体类型的作用,除了不能声明以外,其他与普通变量一样
#include
struct Person{
int age;
char sex;
};
int main(int argc, const char * argv[]) {
struct Person p2;
p2.sex = 's';
p2.age = 10;
struct Person{
int age;
};
struct Person p = {10};
printf("age = %d\n",p.age);
{
struct Person p = {20};
struct Monkey{
char *name;
};
}
return 0;
}
文章图片
5.结构体数组
结构体数组:数组元素为结构体数组
定义结构体数组
结构类型 数组名称[元素个数];
数组元素的类型 数组名称[元素个数];
#include
//一般情况下结构体类型都是定义在函数的外部
struct Dog{
char *name;
int age;
};
void test()
{
//int nums[] = {1,2,3,4};
//结构体如果没有初始化,它里面都是垃圾值
//第一种方式:向定义结构体数组然后初始化
struct Dog dogs[5];
dogs[0] = (struct Dog){"旺财",1};
dogs[1].age = 1;
dogs[1].name = "大黄";
//遍历结构体数组
for(int i = 0;
i < 5;
i++)
{
printf("age = %d,name = %s\n",dogs[i].age,dogs[i].name);
}
}
void test2()
{
//定义结构体数组的同时进行初始化
//如果没有显式初始化的结构体,那么这个结构体中所有成员都会被初始化为0
struct Dog dogs[10] = {{"旺财",1},{"大黄",2},{"来福",3},{"小黑",4},{"小白",5}};
//计算数组的元素个数
int len = sizeof(dogs) / sizeof(struct Dog);
for(int i = 0;
i < len ;
i++)
{
printf("age = %d,name = %s\n",dogs[i].age,dogs[i].name);
}}
int main(int argc, const char * argv[]) {
//test();
tset2();
return 0;
}
文章图片
6.结构体与指针
结构体指针:指向结构体的指针
指针所指向的数据类型 * 指针变量名称;
结构类型 * 指针变量名称;
#include
struct Student{
char *name;
//姓名
int no;
//学号
double score;
//成绩
};
int main(int argc, const char * argv[]) {
struct Student stu = {"大木",60,59};
//定义结构体指针
struct Student *sp1;
sp1 = &stu;
//定义的同时进行初始化
struct Student *sp = &stu;
//通过指针访问结构体的成员的第一种方式
(*sp).score = 60;
//第二种方式(重点)
sp->name = "小木";
sp->no = 59;
printf("name = %s,no = %d,score = %.2lf\n",stu.name,stu.no,stu.score);
return 0;
}
文章图片
7.结构体嵌套
一个结构体内部可以有其他类型的结构体成员
结构体嵌套的注意点:
1、结构体不可以嵌套自己,不能有字节这种类型的成员
2、结构体可以嵌套自己类型的指针
#include
//定义了一个日期的结构体
struct Time{
int hour;
// HH
int minute;
//mm
int second;
//ss
};
struct Date{
int year;
int month;
int day;
struct Time time;
};
struct Employee{
int no;
char name[20];
//入职日期
//int year;
//int month;
//int day;
struct Date inDate;
//生日
//int birthyear;
//int birthmonth;
//int birthday;
struct Date birthday;
//离职日期
//int goyear;
//int gomonth;
//int goday;
struct Date outDate;
};
void test()
{
struct Employee emp = {1,"大幕",{2014,10,14,{12,12,12}},{1990,10,14},{2014,11,14}};
printf("no = %d,name = %s,入职日期 = %d-%d-%d %d:%d:%d\n"
,emp.no,emp.name,emp.inDate.year,emp.inDate.month,emp.inDate.day,
emp.inDate.time.hour,emp.inDate.time.minute,emp.inDate.time.second);
}
struct Person{
char *name;
//struct Person son;
struct Person *son;
};
/*
1.某班有5个学生,三门课。分别编写3个函数实现以下要求:
(1) 求各门课的平均分;
(2) 找出有两门以上不及格的学生,并输出其学号和不及格课程的成绩;
(3) 找出三门课平均成绩在85-90分的学生,并输出其学号和姓名
*/
int main(int argc, const char * argv[]) {
struct Person father = {"father"};
struct Person son = {"son"};
father.son = &son;
printf("son name = %s\n",father.son->name);
return 0;
}
8.枚举
枚举:一个一个列举出来
枚举作用:消除魔法数字
使用场景:当某个东西只有那么几个取值时候就是用枚举
定义枚举格式
enum 枚举类型的名称{
元素,//逗号
...
};
注意点:
1、枚举类型定义中,所有元素都是整形常量
2、枚举类型的本质就是整形
#include
//定义性别枚举类型
enum Sex{
Man,
Woman,
Other
};
//int Man = 10;
//枚举定义之后,后面不可定义与成员相同变量
void test()
{
//在代码中出现的这种表示特殊含义数字,我们魔法数字
//int sex = 0;
enum Sex sex;
printf("%d\n",Man);
int Man = 10;
printf("%d\n",Man);
//sex = 1;
// 这里不能把要给数字赋值给一个枚举类型的变量,这样枚举存在的意义就没有了
//Man = 1;
}
// 可以指定枚举中每一个元素值
enum Season{
Spring = 2,
Summer,
Autumn,
Winter,
SOther = 9
};
void PrintSeason(enum Season season)
{
switch (season) {
case Spring: //Case后面的值务必与枚举中成员一致,不要出现魔法数字
printf("春季\n");
break;
case Summer:
printf("夏季\n");
break;
case Autumn:
printf("秋季\n");
break;
case Winter:
printf("冬季\n");
break;
case SOther:
printf("不是地球上季节\n");
break;
default:
break;
}
}
int main(int argc, const char * argv[]) {
printf("%d,%d,%d\n",Man,Woman,Other);
printf("%d,%d,%d,%d\n",Spring,Summer,Autumn,Winter);
enum Season season = Summer;
PrintSeason(season);
return 0;
}
文章图片
9. typedef:
给已有数据类型起别名
基本数据类型
int char float double
结构体
枚举
指针
1、普通变量的指针
2、结构体指针
3、函数指针
基本数据类型
定义格式:typedef 已有数据类型 别名; 【变量|ios学习之旅------玩转结构体】
#include
void testBaseType()
{
typedef intInt;
Int num = 10;
typedef Int Integer;
Integer a = 20;
printf("%d\n",a);
}
/*
给结构体类型起别名
*/
void testStruct()
{
//第一种方式:先定义结构体类型再给结构体类型起别名
struct _Person{
int age;
char *name;
};
typedef struct _Person Person;
Person p1 = {10,"小红"};
printf("age = %d,name = %s\n",p1.age,p1.name);
// 第二种方式,定义结构体类型的同时给结构体类型起别名
typedef struct _Dog{
int age;
char *name;
} Dog;
Dog dog = {1,"大黄"};
//第三种方式:定义匿名结构体类型的同时给结构体起一个别名
typedef struct{
int age;
char * name;
} Cat;
Cat cat = {1,"tom"};
}
//给枚举起别名
void testEnum()
{
//1、先定义枚举类型然后给枚举起别名
enum _Sex{
Man,
Woman,
Other
};
typedef enum _Sex Sex;
Sex sex = Man;
//2、定义枚举类型的同时给枚举类型起一个别名
typedef enum _Season{
Spring,
Summer
} Season;
Season season = Spring;
//3、定义匿名枚举类型同时给枚举起一个别名
typedef enum {
Cong,
Suan,
Jiang
} TiaoWei;
TiaoWei zuoLiao = Cong;
}
//4、指针类型
//4.1 基本数据类型的指针
void testTypedefBasicPointer()
{
typedefint * IntPointerType;
int a = 10;
IntPointerType p = &a;
*p = 20;
printf("%d\n",a);
}
//4.2 给结构体类型的指针起别名
void testTypedefStructPointer()
{
typedef struct {
char *name;
int age;
} Person;
typedef Person * PersonPointerType;
Person p = {"张三",10};
PersonPointerType pp = &p;
typedef struct _Cat{
char *name;
int age;
} Cat, * CatPointerType;
Cat cat = {"小猫",1};
CatPointerType catPointer = &cat;
printf("name = %s,age = %d\n",catPointer->name,catPointer->age);
}
//4.3 给枚举类型的指针起别名
void testTypedefEnumPointer()
{
//先定义枚举类型
enum _Sex{
Man,
Woman,
Other
};
typedef enum _Sex * SexPointer;
enum _Sex sex = Man;
SexPointer sexPointer = &sex;
*sexPointer = Woman;
printf("%d\n",sex);
}
//4.4 给函数指针起别名
int sum(int num1,int num2){
return num1 + num2;
}
int minus(int num1,int num2){
return num1 + num2;
}
//给函数指针起别名
//typedef 指针所指向的函数的返回值类型 (*函数指针类型别名)(所指向的函数的形参列表);
void testTypedefMethodPointer()
{
//int (*sumPointer)(int num1,int num2) = sum;
//
//int (*minusPointer)(int num1,int num2) = minus;
typedefint (*MethodPointerType)(int num1,int num2);
MethodPointerType sumPointer = sum;
MethodPointerType minusPointer = minus;
int rs =sumPointer(10,20);
printf("rs = %d\n",rs);
}
//了解
void testTypedefArrayPointer()
{
char names[][10] = {"xtf","zbz","wf"};
char (*arrayPoiner)[10];
arrayPoiner = names;
typedef char (*ArrayPointerType)[10];
ArrayPointerType pointer = names;
printf("%s\n",pointer[0]);
}
int main(int argc, const char * argv[]) {
//
//testBaseType();
//testStruct();
testTypedefBasicPointer();
testTypedefStructPointer();
testTypedefEnumPointer();
testTypedefMethodPointer();
testTypedefArrayPointer();
return 0;
}
文章图片
推荐阅读
- Shell-Bash变量与运算符
- 由浅入深理解AOP
- 2020-04-07vue中Axios的封装和API接口的管理
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- (二)ES6第一节变量(let|(二)ES6第一节变量(let,const)
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- iOS中的Block