一、结构体
1.定义结构体
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
2.定义结构体变量的3种方式
2.1 先定义类型,再定义变量(分开定义)
struct Student
{
int age;
};
struct Student stu;
2.2定义类型的同时定义变量
struct Student
{
int age;
} stu;
struct Student stu2;
2.3定义类型的同时定义变量(省略了类型名称)
struct
{
int age;
} stu;
3.结构体的内存分析
3.1定义结构体类型(并不会分配存储空间)
struct Date
{
int year;
int month;
int day;
};
3.2定义结构体变量(真正分配存储空间)
struct Date d1 = {2011, 4, 10};
struct Date d2 = {2012, 8, 9};
3.3会将d1所有成员的值对应地赋值给d2的所有成员
d2 = d1;
d2.year = 2010;
4.补齐算法
struct Student
{
int age;// 4个字节
char a;
//char *name; // 8个字节
};
struct Student stu;
//stu.age = 20;
//stu.name = "jack";
// 补齐算法(对齐算法)
// 结构体所占用的存储空间 必须是 最大成员字节数的倍数
int s = sizeof(stu);
printf("%d\n", s);
5.结构体数组
struct RankRecord
{
int no; // 序号 4
int score; // 积分 4
char *name; // 名称 8
};
struct RankRecord records[3] =
{
{1, "jack", 5000},
{2, "jim", 500},
{3, "jake",300}
};
records[0].no = 4;
6.结构体指针
6.1指向结构体的指针的定义
struct Student *p;
例:
struct Student
{
int no;
int age;
};
// 结构体变量
struct Student stu = {1, 20};
// 指针变量p将来指向struct Student类型的数据
struct Student *p;
// 指针变量p指向了stu变量
p = &stu;
6.2利用指针访问结构体的成员
1> (*p).成员名称
2> p->成员名称
例:
// 第一种方式
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);
7.结构体和函数
//如果结构体作为函数参数,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员
//修改函数内部结构体的成员不会影响外面的实参结构体
struct Student
{
int age;
int no;
};
struct Student stu = {28, 1};
void test(struct Student s)
{
s.age = 30;
s.no = 2;
}
// 会影响外面的实参结构体
void test2(struct Student *p)
{
p->age = 15;
p->no = 2;
}
8.结构体嵌套
struct Date
{
int year;
int month;
int day;
};
// 类型
struct Student
{
int no; // 学号
struct Date birthday; // 生日
struct Date ruxueDate; // 入学日期
// 这种写法是错误的
//struct Student stu;
};
struct Student stu = {1, {2000, 9, 10}, {2012, 9, 10}};
二、枚举
1.定义枚举类型
enum Season
{
spring,
summer,
autumn,
winter
};
2.定义枚举变量并初始化
enum Season s = summer;
三、预处理指令
1.宏定义
1.1常量的宏定义
#define COUNT 4
1.2带参数的宏定义
#define sum(v1, v2) ((v1)+(v2))
#define pingfang(a) ((a)*(a))
int c = pingfang(5+5)/pingfang(2);
int c = sum(2, 3) * sum(6, 4);
2.条件编译
#if (A == 10)
printf("a是10\n");
#elif (A == 5)
printf("a是5\n");
#else
printf("a其他值\n");
#endif
3.文件包含
例:
lisi.c文件内容如下:
int sum(int a, int b)
{
return a + b;
}
lisi.h文件内容如下:
#ifndef LISI_H
#define LISI_H
int sum(int a, int b);
#endif
zhangsan.c文件内容如下:
#include "lisi.h"
#include "wangwu.h"
#include <stdio.h>
int main()
{
int c = sum(10, 19);
printf("c is %d\n", c);
return 0;
}
四、typedef
1.用于基本数据类型
typedef int MyInt;
2.用于指针
typedef char * String;
3.用于结构体
struct Student
{
int age;
};
typedef struct Student MyStu;
4.用于枚举
typedef enum {
Man,
Woman
} MySex;
5.用于指向函数的指针
typedef int (*MyPoint)(int, int);
int minus(int a, int b)
{
return a - b;
}
MyPoint p= minus;
int m = p(2,3);
6.指向结构体的指针
typedef struct Person
{
int age;
} * PersonPoint;
// 定义结构体变量
struct Person p = {20};
PersonPoint p2 = &p;
五、static与extern
1.static和extern对函数的作用
外部函数:定义的函数能被本文件和其他文件访问
1> 默认情况下所有函数都是外部函数
2> 不允许有同名的外部函数
内部函数:定义的函数只能被本文件访问,其他文件不能访问
1> 允许不同文件中有同名的内部函数
static对函数的作用:
1> 定义一个内部函数
2> 声明一个内部函数
例:
static void test2();
static void test2()
{
}
extern对函数的作用:
1> 完整地定义一个外部函数
2> 完整地声明一个外部函数
(extern可以省略,默认情况下声明和定义的函数都是外部函数)
2.static和extern对变量的作用
全局变量分2种:
外部变量:定义的变量能被本文件和其他文件访问
1> 默认情况下,所有的全局变量都是外部变量
2> 不同文件中的同名外部变量,都代表着同一个变量
内部变量:定义的变量只能被本文件访问,不能被其他文件访问
1> 不同文件中的同名内部变量,互不影响
static对变量的作用:
定义一个内部变量
static int b;
extern对变量的作用:
声明一个外部变量
extern int a;
static修饰局部变量的使用场合:
1.如果某个函数的调用频率特别高
2.这个函数内部的某个变量值是固定不变的
static修饰局部变量:
1> 延长局部变量的生命周期:程序结束的时候,局部变量才会被销毁
2> 并没有改变局部变量的作用域
3> 所有的test函数都共享着一个变量b
void test()
{
static double pi = 3.14;
double zc = 2 * pi * 10;
int a = 0;
a++;
printf("a的值是%d\n", a);
static int b = 0;
b++;
printf("b的值是%d\n", b); // 3
}
六、递归思想
/*
pow2(b, 0) == 1
pow2(b, 1) == b == pow2(b, 0) * b
pow2(b, 2) == b*b == pow2(b, 1) * b
pow2(b, 3) == b*b*b == pow2(b, 2) * b
1> n为0,结果肯定是1
2> n>0,pow2(b, n) == pow2(b, n-1) * b
*/
int pow2(int b, int n)
{
if (n <= 0) return 1;
return pow2(b, n-1) * b;
}
int main()
{
int c = pow2(3, 2);
printf("%d\n", c);
return 0;
}