结构体函数
结构体中不能调用函数,需要声明函数指针
#include<stdio.h>
typedef int (*p_func)(int a, int b);
//C++里面面向对象,多态
int add(int a, int b)
{
return a + b;
}
//结构体各成员默认是public
//class在C++里,是一个类,所有成员和方法(函数)是si(private)有的,只能在类里进行访问
//struct里面不能包含函数,但是可以包含函数指针
struct data
{
int a;
int b;
p_func p;//函数指针
//不能有函数
// int add(int a, int b);
}s;
//填充结构体
void set_func(struct data *p)
{
p->a = 2;
p->b = 3;
p->p = add;
}
//业务函数
int cnt_func(struct data *p_str)
{
return p_str->p(p_str->a, p_str->b);
}
int main(void)
{
set_func(&s);
int ret = cnt_func(&s);
printf("ret = %d.\n", ret);
return 0;
}
网络结构体
主流还是ipv4
头文件路径:/usr/include/netinet/in.h
需要用的到头文件
#include <stdio.h>
#include <features.h>
#include <stdint.h>
#include <sys/socket.h>
#include <bits/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
头文件内容:
/* Internet address. */
typedef uint32_t in_addr_t;
typedef uint16_t in_port_t; // 16的无符号short类型
struct in_addr
{
in_addr_t s_addr;
};
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_); /* AF_INET IPv4 Internet protocols 指定网络地址类型*/
in_port_t sin_port; /* Port number. 端口号 16位无符号short */
struct in_addr sin_addr; /* Internet address. 具体的网址32位无符号int*/
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)];
};
定义结构体sockaddr_in并赋值
#define PORT 0x1234
#define ADDR "19.16.1.22"
//把本地ip地址转换成网络字节序地址
//in_addr_t inet_addr(const char *cp);
//输出型参数干的事儿
void set_net_struct(struct sockaddr_in *p)
{
p->sin_family = AF_INET;
p->sin_port = htons(PORT);
p->sin_addr.s_addr = inet_addr(ADDR);
}
int main(void)
{
struct sockaddr_in s;
//赋值
set_net_struct(&s);
printf("网络字节序地址:0x%x.\n", s.sin_addr.s_addr);
return 0;
}
柔性数组
是在结构体里,有一个数组,必须是结构体最后的一个元素,而且由特定形式[]或[0],即结构体的最后一个元素必须是没有定义大小的数组,需要malloc动态申请数组大小后使用
整体的结构体至少有两个成员变量。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int len;
int arr[];
}S;
// 看一下,遍历
void show_infor(S *p)
{
int i = 0;
// printf("p->arr[%d] = %d.\n", p->len-1, p->arr[p->len-1]);
//遍历所有元素
for (i=0; i<p->len; i++)
{
printf("p->arr[%d] = %d.\n", i, p->arr[i]);
}
}
//生成柔性数组
void create_soft_arr(int len)
{
S *p = (S *)malloc(sizeof(S) + sizeof(int)*len);
//让a成员控制我数组个数
p->len = len;
int i = 0;
for (i=0; i<len; i++)
{
if (i <= 1)
p->arr[i] = 1;
else if (i >= 2)
p->arr[i] = p->arr[i-1] + p->arr[i-2];
}
//看一下 用func
show_infor(p);
free(p);
}
int main(void)
{
create_soft_arr(10);
int len = 10;
printf("sizeof(S) = %d.\n", sizeof(S)); // 4
//动态数组生成
//.符号:结构体变量访问各成员.
S *p = (S *)malloc(sizeof(S) + sizeof(int)*len);
//判断空间申请情况,和清0操作,省略
//数组赋值
int i = 0;
for (i=0; i<len; i++)
{
//p->arr得到的是数组名
p->arr[i] = i+1;
// (*p).arr[i] = i+1;
}
//看一下
for (i=0; i<len; i++)
{
printf("p->arr[%d] = %d.\n", i, p->arr[i]);
}
return 0;
}
枚举
枚举:定义常量符号,就是宏定义常数的集合体
比如:四季,星期,意义相关的常数
状态机:1、根据当前状态,这个周期结束,就成了下一个状态。
2、根据你的当前状态,还和你的输入有关。比如:fpga, GUI(用户图形交互界面)
实现:密码锁
#include <stdio.h>
#define NU1 10
#define NU2 10
//里面成员必须大写
typedef enum fangxiang // 标识符
{
EAST,
WEST = 99,
SAUTH,
NORTH = 100,
xq,
}E;
//定义状态机的所有状态集
typedef enum STATE
{
STATE1,
STATE2,
STATE3,
STATE4,
STATE5,
STATE6,
STATE7,
}S;
int main(void)
{
int num = 0;
//1、密码锁初始状态
S current_state = STATE1;
// 输入密码,进行解锁
printf("输入一个密码数字:");
while (1)
{
scanf("%d", &num);
printf("num = %d.\n", num);
//解锁子开始
switch (current_state)
{
case STATE1:
if (num == 9)
{
current_state = STATE2; // 用户每输对一次,进入下一状态
}
else
{
current_state = STATE1;
}
break;
case STATE2:
if (num == 5)
{
current_state = STATE3; // 用户每输对一次,进入下一状态
}
else
{
current_state = STATE1;
}
break;
case STATE3:
if (num == 2)
{
current_state = STATE4; // 用户每输对一次,进入下一状态
}
else
{
current_state = STATE1;
}
break;
case STATE4:
if (num == 7)
{
current_state = STATE5; // 用户每输对一次,进入下一状态
}
else
{
current_state = STATE1;
}
break;
default:
current_state = STATE1;
break;
}
if (current_state == STATE5)
{
printf("开了锁,请进!.\n");
//break
return 0;
}
if (current_state == STATE1)
{
printf("初始状态.\n");
}
}
}