【7.13-7.15】学习总结

目录

 【1】Linux下的C语言

1.sqlite3库的移植

(1)移植于Linux中运行(X86)

(2)移植于ARM中使用

2.共用体与结构体

(1)共用体与结构体的区别

(2)结构体字节对齐原则

(3)代码实例

3.内核链表

(1)Linux内核中的链表

(2)代码实例

【2】Git

1.Git简介

2.Git安装

3.Git使用

【3】JSON

1.JSON简介

2.JSON操作

3.代码实例


本次我将从以下思维导图中的三方面来进行总结:

 【1】Linux下的C语言

1.sqlite3库的移植

(1)移植于Linux中运行(X86)

移植步骤:

1> 从官网获取源码,将获取到的源码放到Linux下的一个目录文件中;

解压源码,并进入解压后生成的目录文件;

tar xf sqlite-autoconf-3140100.tar.gz  //解压源码

在此目录下新建一个目录文件如“work,以便后续安装。 

2> 配置编译选项

./configure --prefix=$PWD/work  //配置编译选项为当前绝对路径下的work目录文件

//configure是一个可执行的配置脚本(用来生成Makefile)
//--prefix:指定安装目录(如果不指定此选项,那么默认安装到系统路径)

//此命令在源码解压后生成的目录文件下执行

3> 编译、安装

make
make install

//此命令在源码解压后生成的目录文件下执行

安装成功后,work目录下的install目录会有:头文件(include)以及库文件。

此时我们就可以写一个测试代码去测试是否能正常编译执行了。测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sqlite3.h>

int main(int argc, const char *argv[])
{
	sqlite3 *db = NULL;

	if (argc != 2)
	{
		printf("usage:%s <db_name>\n", argv[0]);
	}
  
	if (sqlite3_open(argv[1], &db) != SQLITE_OK)
	{
		printf("err\n");
		exit(EXIT_FAILURE);
	}

	sqlite3_close(db);

	return 0;
}

gcc编译后发现,提示“找不到头文件”、“未定义”、“找不到库”等错误或警告,所以在编译时需要指定头文件位置:

//gcc 源文件 -I <头文件路径> -L <库路径> -l<库名称>
  gcc sqlite.c -I ./include -L ./lib/ -l sqlite3

//此命令建立在 .c源文件放在之前创建的work目录文件 的前提下

4> 配置系统路径

以上步骤已经生成了可执行文件a.out,但当我们执行时又出现了错误:

./a.out: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file: No such file or directory

 这是因为运行时所需要的库找不到,Linux在运行时默认的查找目录为/lib或者/usr/lib,所以,我们需要把编译出来的库拷贝到上面两个路径中任意一个即可。

拷贝时需要注意:命令中需要增加-d选项,保持库的软链接属性。

sudo cp libsqlite3.so* /usr/lib -d  //libsqlite3.so* 在work目录下的lib目录里

(2)移植于ARM中使用

只需在配置编译选项步骤换成这一步即可:

./configure --host=arm-linux-  --prefix=$PWD/work

//--host:指定编译器

2.共用体与结构体

(1)共用体与结构体的区别

        共用体:共用体成员内部共用同一块内存区域

        结构体:单独分配内存空间

(2)结构体字节对齐原则

        首地址对齐(按最大字节对齐)

        总大小对齐(按最大字节对齐)

        成员对齐(按当前成员类型对齐)

详细解释:结构体字节对齐3原则

(3)代码实例

typedef int BOOL;

union val_t
{ 
    BOOL b_val;  //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val;  //浮点值存储空间
};

此例要求:

        ①定义一个val_t类型的变量a,对a的f_val进行赋值,然后打印f_val成员的值。

        ②再定义一个val_t类型的变量b,将a的值赋给变量b。

        ③比较变量a和变量b是否相等。

#include <stdio.h>
#include <string.h>

typedef int BOOL;

union val_t
{ 
    BOOL b_val;  //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val;  //浮点值存储空间
};

int main()
{
	union val_t a;
	a.f_val = 5.2;
	printf("a.f_val = %f\n",a.f_val);
	
	union val_t b = a;
    printf("b.f_val = %f\n",b.f_val);

	if (memcmp(&b,&a,sizeof(union val_t)) == 0) //内存比较
    {
        printf("a = b\n");
    }
    else
    {
        printf("a != b\n");
    }
	return 0;
}

3.内核链表

(1)Linux内核中的链表

        Linux在2.1的内核中就引入了官方链表,其头文件是:

#include <linux/list.h>

        关于Linux的内核链表这里有更详细的介绍:linux内核中的链表。 

(2)代码实例

"data": 
[
    {
      "key": 1,
      "type": 2,
      "val": "10"
    },
    {
      "key": 2,
      "type": 1,
      "val": "0"
    },
    {
      "key": 3,
      "type": 3,
      "val": "22.5"
    }
]

本次实例的要求是:

将上面的数据节点信息转换为链表结构,并遍历输出。要求根据type的值来决定val的类型。type为1代表bool类型,2代表整形,3代表浮点型。无需解析文本,直接赋值形成节点即可。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "list.h"

union type_val     //val类型共用体
{
	bool bool_val;
	int int_val;
	float float_val;
};

struct node_list    //节点结构体
{
	int key;
	int type;
	union type_val val;
	struct list_head list; //链表
};

int main(int argc, const char *argv[])
{
	//定义结构体变量,并初始化节点
    struct node_list node[3] = {{1,2},{2,1},{3,3}};
	node[0].val.int_val = 10;
	node[1].val.bool_val = 0;
	node[2].val.float_val = 22.5;

	struct list_head head;  //定义链表变量
	INIT_LIST_HEAD(&head);
	list_add(&node[0].list,&head);  //加入链表
	list_add(&node[1].list,&head);
	list_add(&node[2].list,&head);

	struct list_head *pos;
	struct node_list *tmp;

	list_for_each(pos,&head)  //遍历输出链表
	{
		tmp = list_entry(pos,struct node_list,list);
		printf("key: %d type: %d ",tmp->key,tmp->type);
		if(tmp->type == 1)  //根据type不同,输出不同的val
		{
			printf("val: %d\n",tmp->val.bool_val);
		}else if(tmp->type == 2)
		{
			printf("val: %d\n",tmp->val.int_val);
		}else if(tmp->type == 3)
		{
			printf("val: %.2f\n",tmp->val.float_val);
		}
	}
	return 0;
}

【2】Git

1.Git简介

        Git是目前世界上最先进的分布式版本控制系统。 所谓版本控制系统,即记录文件的每一次改动,不用再手动“另存为”一堆的文件。并且Git还可以和别人一起协同编辑文件。

Git详细简介:Git简介

        分布式版本控制系统较集中式版本控制系统有明显的优点:版本提交无需依赖服务器。

分布式:每一台客户端都有完整的版本备份,版本提交无需依赖服务器。只有多人协作时,需使用服务器完成版本库的交换。

集中式:所有的版本库都存在中央服务器,本地备份依赖中央服务器。如果服务器出现问题,或网络不好,则无法完成备份。

2.Git安装

        Git安装步骤及安装包:Git的安装(附安装包)。 

3.Git使用

        1> Git的使用分为三个区域:工作区版本库以及远程仓库

工作区:可以理解为当前所要操作的文件夹,就是一个工作区,并且也是在此文件夹下创建版本库。

版本库:就是Git备份的位置,它是一个隐藏的文件夹,目的就是不希望人们去修改它。

远程仓库:就是远程服务器,也是代码及数据的托管平台。比如GitHub、GitLab和码云等。

        2> Git操作:创建版本库、提交、还原、回退及前进等。

创建版本库:

        新建文件夹,在右键菜单中选择:创建版本库。

         注意不要直接在桌面点击创建版本库,因为本身桌面也是一个文件夹,创建也是生效的。如果把桌面做成版本库,可以把windows文件夹中隐藏项目选项打开,然后把桌面上的隐藏文件夹.git删除即可恢复。

 提交:

        在已创建版本库的文件夹下右击。

        注意:工作区如果没有修改,是无法触发提交动作的。

丢掉(还原):

此动作指:当工作区已修改,但还未进行“提交”动作时,选择放弃刚刚修改的内容。

        在已创建版本库的文件夹下右击。

        注意工作区如果没有修改,是无法触发还原动作的。

回退:

        先找到版本日志,然后选择某个版本进行回退。

 前进:

        与回退不同的是,前进需要找到“显示引用记录”,里面才可以进行版本的前进。

 

【3】JSON

1.JSON简介

Json是一种轻量级的数据交换格式,它共有六种基本数据类型,分别是:

number  //相当于C中的int类型(数字)
boolean //相当于C++中的bool型
string  //相当于C++中的string类型、C中的char*型(字符串)
null    //相当于C中的NULL型
array   //相当于C中的数组[]
object  //相当于C++中的类、C中的结构体{}

Json遵守非常严格的格式

//格式
JSON以大括号“{}”起始和结尾
内容以键值对的形式存在,并且所有的健都是字符串
值的类型就是六种基本数据类型
每个键值对以“,”分割,最后一个键值对不加“,”

//例子
{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

这里有Json更详细的入门教程:Json入门教程。 

2.JSON操作

        Json的操作分为两种,分别是序列化反序列化。 

序列化:利用程序生成Json字符串的过程。

反序列化:利用程序将已有的Json字符串解析出我们需要的值的过程。

        使用cJSON这是一个详解cJSON使用详解。 

3.代码实例

本次实例要求:

①使用cJSON库对下面的JSON文件进行反序列化操作。ver和cloud的节点直接打印,data的数据节点解析后形成链表(使用内核链表)存储(将下面内容存为文件,读取后解析)。

②解析完成后,再重新序列化为json字符串直接打印。 

{
	"ver": "1.0",
	"cloud": {
		"password": "12345678",
		"mpassword": "12345678"
	},
	"data": [{
      "key": 1,
      "type": 2,
      "val": "10"
    },
    {
      "key": 2,
      "type": 1,
      "val": "0"
    },
    {
      "key": 3,
      "type": 3,
      "val": "22.5"
    }
	]
}

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cJSON.h"
#include "list.h"

#define BOOL int

union val_t
{
	BOOL b_val;
	int i_val;
	float f_val;
};

struct data
{
	int key;
	int type;
	union val_t val;
	struct list_head list;
};

int main(int argc, const char *argv[])
{
	/****************** JSON反序列化 ********************/

	char buf[310] = {0}; //存放jsonStr内容
	char *jsonStr = buf; //指向buf的指针

	//1 读取json内容
	FILE *fd = fopen("./jsonStr.txt","r"); //打开jsonStr文件
	if(fd == NULL)
	{
		perror("fopen jsonStr.txt err");
		return -1;
	}
	if(fread(buf,sizeof(char),310,fd) < 0) //读取jsonStr文件内容
	{
		perror("fread jsonStr.txt err");
		return -1;
	}

	//2 创建cJSON对象,并打印ver和cloud内容
	cJSON *root = NULL;
	cJSON *item = NULL;

	printf(" 1.JSON反序列化:\n");

	root = cJSON_Parse(jsonStr);
	if(!root)
	{
		printf("Error before:[%s]\n",cJSON_GetErrorPtr());
	}else
	{
		item = cJSON_GetObjectItem(root,"ver"); //打印ver内容
		printf("ver:%s\n",cJSON_Print(item));

		item = cJSON_GetObjectItem(root,"cloud"); //打印cloud内容
		printf("cloud:%s\n",cJSON_Print(item));
	}

	//3 创建链表,存放data数据
	int i,sizeJson;

	cJSON *posJson = NULL;
	cJSON *dataJson = NULL;

	struct list_head head; //链表
	INIT_LIST_HEAD(&head);

	item = cJSON_GetObjectItem(root,"data"); //计算data数组有多少成员
	sizeJson = cJSON_GetArraySize(item);

	for(i = 0;i < sizeJson;i++) //循环加入链表中
	{
		struct data *node = (struct data*)malloc(sizeof(struct data));

		item = cJSON_GetObjectItem(root,"data");
		dataJson = cJSON_GetArrayItem(item,i); //获取了data数组中的第i组数据

		posJson = cJSON_GetObjectItem(dataJson,"key");
		node->key = posJson->valueint; //将key的值放到了结构体中

		posJson = cJSON_GetObjectItem(dataJson,"type");
		node->type = posJson->valueint;

		posJson = cJSON_GetObjectItem(dataJson,"val");
		switch(node->type) //根据type转换val,然后赋给结构体
		{
			case 1:node->val.b_val = atoi(posJson->valuestring);break;
			case 2:node->val.i_val = atoi(posJson->valuestring);break;
			case 3:node->val.f_val = atof(posJson->valuestring);break;
		}
		
		list_add(&node->list,&head); //加入链表
	}

	//4 打印链表中的内容
	struct list_head *pos;
	struct data *tmp;

	list_for_each(pos,&head)                           
	{
		tmp = list_entry(pos,struct data,list);
		switch(tmp->type)
		{
			case 1:printf("type:%d val:%d\n",tmp->type,tmp->val.b_val);break;
			case 2:printf("type:%d val:%d\n",tmp->type,tmp->val.i_val);break;
			case 3:printf("type:%d val:%.2f\n",tmp->type,tmp->val.f_val);break;
		}
	}

	/****************** JSON序列化 **********************/
	
	//5 构建json
	cJSON *json_root = cJSON_CreateObject();
	cJSON *json_item = cJSON_CreateObject();
	cJSON *json_next = cJSON_CreateArray();
	cJSON *json_next_item1 = cJSON_CreateObject();
	cJSON *json_next_item2 = cJSON_CreateObject();
	cJSON *json_next_item3 = cJSON_CreateObject();

	//在根节点下添加ver节点
	cJSON_AddItemToObject(json_root,"ver",cJSON_CreateString("1.0"));

	//在根节点下添加cloud节点
	cJSON_AddItemToObject(json_root,"cloud",json_item);
	//在cloud节点下添加password和mpassword节点
	cJSON_AddItemToObject(json_item,"password",cJSON_CreateString("12345678"));
	cJSON_AddItemToObject(json_item,"mpassword",cJSON_CreateString("12345678"));
	
	//在根节点下添加data数组节点
	cJSON_AddItemToObject(json_root,"data",json_next);

	//在data数组节点下添加一个节点
	cJSON_AddItemToObject(json_next,"",json_next_item1);
	//在此节点下添加key、type和val节点
	cJSON_AddItemToObject(json_next_item1,"key",cJSON_CreateNumber(1));
	cJSON_AddItemToObject(json_next_item1,"type",cJSON_CreateNumber(2));
	cJSON_AddItemToObject(json_next_item1,"val",cJSON_CreateString("10"));
	
	cJSON_AddItemToObject(json_next,"",json_next_item2);
	cJSON_AddItemToObject(json_next_item2,"key",cJSON_CreateNumber(2));
	cJSON_AddItemToObject(json_next_item2,"type",cJSON_CreateNumber(1));
	cJSON_AddItemToObject(json_next_item2,"val",cJSON_CreateString("0"));
	
	cJSON_AddItemToObject(json_next,"",json_next_item3);
	cJSON_AddItemToObject(json_next_item3,"key",cJSON_CreateNumber(3));
	cJSON_AddItemToObject(json_next_item3,"type",cJSON_CreateNumber(3));
	cJSON_AddItemToObject(json_next_item3,"val",cJSON_CreateString("22.5"));

	printf("\n 2.JSON序列化:\n%s\n",cJSON_Print(json_root));

	//关闭jsonStr文件
	fclose(fd);
	return 0;
}

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

担心头发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值