c语言基础(九)

结构体函数

结构体中不能调用函数,需要声明函数指针

#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");
            }
    }
}

猜你喜欢

转载自blog.csdn.net/linzetao233/article/details/78915435
今日推荐