【留下笔记】实习过程中查询过的问题,留下来

前言

实习接近尾声,其实嘛,收尾工作特别少的!就把本次实习过程遇到的问题或知识点记录下来,供自己将来无聊之时方便回顾。

C语言

数组名和指针?
答:数组名可以当做指针使用,因为数组名可以表示改数组第一个元素的地址;但不能将数组名理解成指针,两者区别很大。
内存申请相关函数:malloc、ralloc、free
void * malloc(size_t size); //申请size个字节的内存空间
void *realloc(void * prt,size_t size ); //跳帧之前malloc、calloc、realloc所分配ptr所指向的内存卡大小。

char c = ‘我’ 正确吗?
错误,一个char占一个字节,而一个汉字占3个字节存储。char *c = “我”;

栈空间和堆空间?
答:程序中定义的临时变量,函数运行(用于压栈),等,都是在栈空间;而申请的内存(malloc),一般都是堆空间。
C语言内存映射关系图

内存区域变量数据可读可写性
栈区函数中的普通变量可读可写
堆区动态申请的内存可读可写
静态变量区static修饰的变量可读可写
数据区用于初始化变量的常量只读
代码区代码指令只读
  1. static修饰的变量,在程序运行过程中不会被销毁,再次使用时会保留上一次的值。
  2. extern关键字,导入其他文件中的函数或变量,常用于某个变量在多个文件中使用的时候,或者仅某一个函数在多个文件中使用(如果是多个函数,就可以采用头文件方式导入其他文件使用)。
  3. 栈区是由系统自动分配的,速度较快,满足栈后进先出的原则,用于存放函数参数、局部变量的值等。栈区最先进入的是main函数,栈的大小一般为1或2M,一般不会超过10M。
  4. 堆区,由程序员申请得到,其大小和虚拟内存大小相关,比如机器自身是32位的,支持的内存则为4G。内存申请之后,必须释放,不然会造成内存泄漏。
  5. 【注】:编写代码时要仔细思考栈是否溢出? 申请使用的内存,使用结束后一定要释放。

strncpy,strcpy,strlen,strcat,memcpy,memset,strchar,strcmp,strncmp,memcmp?

  1. strcpy和strncpy的区别:char *strcpy(char *dest,const char 8src); char * strncpy(char *dest,const char *src,size_t n); //strcpy 遇到0就结束,而strncpy要复制n个字节才结束,如果中途遇到0,之后拷贝的内容都会是0.
  2. 避免strncpy遇到0后,后面都会拷贝0的问题,用memcpy内存拷贝,其只在乎拷贝长度,不在乎拷贝内容。memcpy(s1+10,s2,5); //这样可以实现字符串拼接的效果
  3. strlen和sizeof的区别,strlen 是返回str的长度,但不包括末尾自动添加的’\0’;sizeof用于获得变量和数据类型的所占内存字节的大小。
  4. void * memset(void *str ,int c,size_t n);复制字符c到参数srt所指向字符串的前n个字符;常用于初始化和清零。
  5. char * strchar(const char* str ,int c ); //返回在字符串str中,第一次出现字符c的位置
  6. strncmp,strcmp,memcmp:字符串比较、内存比较,相同返回0,不同返回非零。

复合数据类型
结构体:struct,多种变量共同组成。结构体指针使用->符号来选择成员变量。

typdef struct _HELLO_{
	int i;
	int j;
	char hello[1024];
}HELLO,*pHELLO;//取别名

union,联合体,共享内存存储,占内存为最大内存变量所占内存的大小。技巧1:可以巧妙地实现类型转转,因为值存在同一个内存中,用不同的类型去读取表现出来的类型不一样。
enum,枚举,一 一对应的关系,相当于规定变量的取值。

一种神奇的用法:
gmssl中skf接口的外壳;将各个函数指针组合定义成一个结构体,然后申请一个该结构体大小的内存,定义一个指针执行这片内存,利用这个结构体指针来调用各个函数。//这个结构体是由函数指针组成的,这个结构体所占的内存就很小。

位、字节:
位是计算机中最基本的单位,要么是0要么是1,。字节即一个字节,一个字节有8位。比如某些环境(与具体操作系统位数有关)下C语言的char类型就是1个字节,最大255.int是2个字节 16位;long是4个字节 32位。
野指针、空指针、空字符串:
野指针:不知道指向哪里的指针,解引用会非常危险。
空指针:指向NULL的指针,NULL的值为0,其实就是一段根本不会使用的内存。
空字符串:只包含一个’\0’的字符串。

C程序跳转关键字:

  1. break:用在switch–case中,while、for等循环也可以用,就直接跳出循环了。
  2. continue:结束本次循环,但不跳出循环,去开始下一次循环。
  3. goto:无条件跳转,能不用就不用,若要用要巧妙地同;比如统一退出口,合理释放申请的资源。
  4. return:返回值,退出函数。

#define 定义常量,而关键字const ,将变量转化为常量

/*指针常量*/
int * const p; //指针类型的变量,这个变量指向的指针地址不能修改,但指针地址所指向的内容可以修改。
int a,b;
int * const p = &a;
*p = 3;  //正确
p = &b;  //错误
/*常量指针*/
const int *p;//常量指针,指向常量的指针,这个指针地址所指向的内容不可以修改,但可以修改指针变量指向的地址。
int a,b;
const int *p = &a;
*p = 3; //报错,常量指针,指向常量的指针,其指向的值不能修改。
p = &b; //正确,常量指针,可以修改其指向的地址。
/*指向常量的常量指针(本质上没有什么意义)*/

位运算:
或 | ;与 & ; 取反 ~;异或 ^

运算操作运算符号
就是竖线啦
‘&’
取反‘~’
异或‘^’

C 语言库函数assert()函数
assert(),如果不满足条件,就返回错误,输出一条srderr,然后终止程序。
常用方法:
1. 空指针检查。asser(pointer!=NULL);
2. 检查函数参数的值。如果某参数必须大于0才执行,assert(a>0);如果小于0就返回错误终止程序
【注】:函数判断后,不仅返回错误,还会终止程序哦。

数组指针和指针数组

/*数值指针,指向数组的指针,还是一个指针*/
char *p[4] = "abc";   //数组指针,等价于 char *(p[4]) = "abc"; 
/*指针数组,成员变量是指针的数组,还是一个数组*/
char (*p)[4] = {"Hello","C","World","!"};  //指针数组,()的优先级最高

C语言错误处理:

// errno;
//perror();
//strerror();

C语言配置文件读取
iniparser.c和iniparser.h是一套小而稳定的配置文件读取函数接口。
解析配置文件ini

C语言测试框架
check是一套C语言测试框架。
check使用方法:开源项目,多看readme,里面有使用的详细过程,结合demo程序,将实现快速上手。

  1. 定义测试套件,天剑测试用例,对C语言函数接口进行测试。
  2. 测试时,尽量覆盖函数内的各个路径。(因此,写代码时功能要考虑周全)
  3. 测试时,还要验证功能正确性,输入输出等。

check官网

形参和实参?
形参,定义函数名或函数体的时候使用的参数,目的是用来接受调用该函数时传进来的参数。
实参,在调用时传递给该函数的参数。
【注】:形参智能在被调用时才分配内存单元,在调用结束时,即可释放内存,因此形参智能在函数内部有效,所以形参不能改变实参。
【注】:若想改变实参,方法:1.用指针 2. 用全局变量

main函数
在程序启动时会去找main函数,然后从此开始执行。

int main(int argc,const char * argv[]){
	//......
}
//arg = argument ,参数
//argc = argument count ,调用main函数时传递agrv值得个数
//argv = argument value ,

#define typdef

/*
typdef常用来定义一些标识符和关键字的别名,它是语言编译过程的一部分,但不实际分配内存,主要是为了提高程序的可读性
*/
typdef int INT;
typdef int* pINT;
/*
#define是宏定义,不在语言编译过程,在程序预编译过程中完成。
*/
#define A(a,b) ((a)+(b))
#define HW "Hello,World!"

C语言资源大全中文网 :C语言资源大全中文网

git 指令

/*一套简单的git使用流程*/
git clone -b develop + 地址/版本  //其中-b 是选择分支,版本号非必选,为空则默认最新版本
/*开发工作*/
git add + 某个文件/文件夹  //而我常用的是在VScode添加了git插件,可以方便的单个或多个文件添加。
git status  //查看本地库状态,是否有add成功
git commit -m "说明"  //添加本次版本修改的一些说明
git push //将本次版本上传至云端

/*git 其他指令*/

git branch    //查看分支
git branch -r  //查看远端库分支
git branch -a //查看当前所有分支(包括本地分支和远端库分支)
git branch -d AAA //删除分支AAA
git checkout AAA  //切换到AAA分支
git pull				//取回远程仓库的变化,并与本地分支合并
git rest  				//重置暂存区,与上一次commit保持一致,但工作区不变

Linux指令

哈哈哈,有点划水了哈,特别少。

mkdir build #创建文件目录
cd build #进入文件目录
ls #查看当前路径下的文件
cd .. #返回到上一级目录
sudo su #普通用户临时申请超级用户权限
sudo + 指令 #以root用户的权限执行本条指令
pwd #查看当前路径
ifconfig #查看ip 和windows下ipconfig一样
cp -a test/ newtest # cp [options] source directory
touch #用于修改文件或目录的时间属性,如果不存在,就立即创建一个。

makefile与gcc

一个最最简单的makefile例子

main: hello.c mian.c
		gcc hello.c main.c -o mian
#最简单的gcc命令: gcc 源程序.c -o 输出目标文件名

makefile中notdir,wildcard和patsubst
1.makefile里的函数
makefile里的函数用法和取变量的值类似,是以’$'开始,然后是一个括号里是函数名和需要的参数列表,若多个参数使用逗号隔开,例如:return = $(functionname arg1,arg2,arg3)
2.notdir
作用:去除所有路径信息,使得SRC里的文件列表只有文件名,没有路径。(主要是消除指令路径下文件名 包含的路径信息)。
3.wildcard函数
使用SRC = $(wildcard*.c ./foo/*.c)
作用:搜索当前目录和指定目录(如 ./foo/)下所有以.c结尾的文件,生成一个以空格间隔的文件名列表,并赋值为SRC。
【注】:当前目录下只有文件名,如(wildcard*.c);而其他目录下的文件要包含路径信息,如(./foo/*.c)
4.patsubst函数
使用OBJ = $(patsubst %.c %.o $(SRC))
作用:patsubst 是匹配替换功能。这句是在SRC中找到所有.c结尾的文件,然后把所有.c换成.o
makefile基础知识一
1. $@ #表示目标文件,包括完整的目标文件名,带有扩展名
$^ #表示所有依赖文件,但不含有重复的依赖文件,以空格隔开
$< #表示第一个依赖文件
反斜杠()是换行符,便于makefile文件的阅读。
2. makefile可以定义变量;这有点像C语言中宏定义字符串
3. makefile自动推到功能,make看到.o文件 会自动将.c文件添加到依赖中,并且gcc -c *.c 也会被推出来
4. PHONY是一个伪目标。
5. 使用make指令,默认make第一个目标。 如果要make其他目标, 使用 make + target

make流程
1.makefile中分为三种: 目标 依赖 代码
2.makefile文件主要包含的5个部分:
1.显示规则:目标 依赖 代码
2.隐式规则:自动推到
3.变量定义: 类似于C语言中宏定义字符串, $() 这样使用变量, 使用函数也是这样的哦
4.文件指示:1.一个makefile引用另外一个makefile 2.指定makefile的有效部分 3.定义多行命令
5.注释。makefile文件只有行注释,#。 可以用反斜杠转移 ,输入# ,如#

makefile中常见预定义变量
AR 库文件维护程序的名称,默认值为ar
AS 汇编程序的名称,默认值为as
CC C编译器的名称,默认值为cc
CPP C预编译器的名称,默认值为$(CC) -E
CXX C++ 编译器的名称,默认值为g++
FC FORTRAN编译器的名称,默认值为f77
RM 删除文件程序的名称,默认值为rm -f
ARFLAGS 库文件维护程序的选项,无默认值
ASFLAGS 汇编程序的选项,无默认值
CFLAGS C编译器的选项,无默认值
CPPFLAGS C预编译器的选项,无默认值
CXXFLAGS C++编译器的选项,无默认值
FFLAGS FORTRAN编译器的选项,无默认值

linux下.a .o .so文件是什么? 有什么作用?
.o 就是objet ,也就相当于windows下编译的obj文件,俗称目标文件
.a 就是archive,也就是相当于windows的VC下编译的lib文件,俗称静态文件。
.o文件是链接文件;.a是静态文件 依靠.o文件生成,作为一个库为外部程序提供函数 接口。
生成.o文件: gcc -c test.o test.c
生成.a文件: ar cqs test.a test.o
.o 就相当于windows里的obj文件,一个.c或.cpp文件对应一个.o文件
.a 是好多个.o合在一起,用于静态链接,即STATIC mode,多个.a可以链接生成一个exe的可执行文件
.so是shared object,用于动态链接的,和windows的dll差不多,使用时才载入。
生成.so文件:gcc -shared *.o -o *.so

C/C++中gcc和g++的对比与区别,及g++的常用参数说明
对比:
1.gcc是GCC中的c编译器,g++是GCC中c++编译器
2.对于后缀是.c的文件,gcc当成c文件处理,而g++当做c++处理;对于cpp文件,都当成.cpp文件处理
3.在编译阶段,g++会自动连接STL库,而gcc必须要加一个参数-lstdc++
4.gcc编译c文件时,可以用的预定义宏比较少。
误区:
1.gcc只能用来编译c文件,g++只能用来编译.cpp文件
2.编译只能用gcc,链接只能用g++
3.gcc不会定义-cpluspuls宏,而g++会。这个宏只是标志着编译器把代码按c还是c++语法解释。
g++常用参数说明:

  1. -c 表示编译代码
  2. -o 表示指定生成的文件名
  3. -g 表示编译时候加入调试符号信息,debug时候需要这些信息。
  4. -I(大写i) 表示设置头文件路径,如-I./表示头文件路径为./
  5. -Wall 表示输出所有警告信息
  6. -D表示设置宏定义,-DDEBUG表示编译debug版本,-DNDEBUG表示编译release版本
  7. -O表示编译时候的优化级别,有四个级别-O0 -O1 -O2 -O3,-O0表示不优化,-O3表示最高优化级别
  8. -shared 表示生成动态链接库
  9. -L 指定库路劲,如-L. 表示库路径为当前目录
  10. -l(小写L)指定库名,如-lc表示应用libc.so

GCC流程
-预处理(Preprocessing)
-编译(Compilation) :是一个.c文件 或.cpp文件的编译
-汇编(Assembly):将汇编语言转换成二进制
-链接(Linking)

预处理 : g++ -E test.cpp >test.ii # 使用了重定向 , 预处理后生成了一个新的源码,将新的源码重定向输入到test.ii中
编译: g++ -S test.ii #编译预处理后的test.ii文件 ,然后生成汇编代码 test.s
汇编: g++ -c test.s #汇编,将汇编代码转成二进制代码, test.o文件
链接: g++ test.o -o test # 将二级制文件链接成 执行文件 ,即将一个test.o二级制文件链接成一个可执行文件test

linux下默认的头文件和库文件所在位置
库文件: /usr/local/lib
头文件: /usr/local/include
默认链接的配置文件,是在 /etc/下

cmake

cmake是一套自动编写makefile的工具, 其语法支持大小写,甚至混写;一般只有全局变量用大写,其余均小写。

#cmake三个基本东西
cmake_minimum_required #最低要求版本
project #设置项目信息
add_executable#指定生成目标

一个例子

# cmake 要求的版本要求说明  如果没有会发出警告
cmake_minimum_required(VERSION 3.0.0)
#设置项目的一些基本信息 。 项目名  开发语言 版本等
project(ssm_skf LANGUAGES C VERSION 1.0.0)
#定义变量 给变量赋值
set(CMAKE_BUILD_TYPE "Debug")
# set(CMAKE_BUILD_TYPE "Release")
# ${}使用定义变量的方法
set(${CMAKE_C_FLAGS_DEBUG} "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") #其实就是gcc后面的各种参数

if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    add_definitions(-DDEBUG )  #用于控制 代码的开启 或 关闭
endif()

set(CMAKE_C_FLAGS  "${CMAKE_C_FLAGS} -std=c99")

#添加头文件路径
include_directories(./src ./inc ./test)
#添加源文件路径 并给其取别名
aux_source_directory(./src SRCS)
#添加定义 用于控制 代码的开启 或 关闭
add_definitions(-D_GNU_SOURCE )
#连接库文件路径
link_directories(./lib ./test/lib)
#生成连接库 并指明其使用的源文件
add_library(${PROJECT_NAME} SHARED ${SRCS})
add_library(${PROJECT_NAME}-static STATIC ${SRCS})

set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0 SOVERSION 1)
set_target_properties(${PROJECT_NAME}-static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/src/skf_api.h")

# target_link_libraries(${PROJECT_NAME} sqlite3 crypto zlog dl pthread m)

# 连接的库
target_link_libraries(${PROJECT_NAME} sqlite3 crypto zlog dl pthread m rt subunit check)

link_libraries(libsm2_cosign.so libgmp.so)


#添加目标代码源文件路径 并给其取别名 目标代码源文件包含有main()函数
aux_source_directory(./test TEST_SRCS)
#执行 生成可执行文件
add_executable(test_${PROJECT_NAME} ${TEST_SRCS})
target_link_libraries(test_${PROJECT_NAME} ${PROJECT_NAME})

aux_source_directory(./tool TOOL_SRCS)
add_executable(ssmctl ${TOOL_SRCS})  #指定生成目标
target_link_libraries(ssmctl ${PROJECT_NAME})

install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-static 
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
        PUBLIC_HEADER DESTINATION include)

include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_GENERATOR "TGZ")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
include(CPack)

gdb

gdb是linux环境下一个很好用的调试工具
gdb 可执行文件名 // gdb helloc 加载可执行程序准备调试
/常用gdb指令/

指令功能
rrun 直接调到断点处,没有设置断点的话直接运行程序
b 源文件名:fun设置一个断点breakpoint在函数”fun”的最开始. 如,b test.c:mian
b 源文件名:N在当前运行源文件的第N行设置断点
b 源文件名:N在当前源文件file.c的第N行设置断点
info break显示所有断点信息
d N删除标号为N的断点
c继续(continue)运行程序,一直到下一个断点或程序结束
f运行直到当前函数(function)结束
s按step调试1行,会进入函数体 (逐步调试)
s N按step调试接下来的N行
n调试1行,与按s命令不同的是此处不进入函数体(单步调试)
p var输出(print)变量”var”的值
set var=val设置变量”var”的值
bt打印调用堆栈(stack trace)
q退出gdb

windows常用的三个指令

指令功能
cd切换目录,如 cd … cd C:\dir1
盘号:切换根目录,如D: E:
dirdirectory显示当前所处目录下的文件和文件夹
mdmake directory 创建目录
rdremove directory
cdchange directory
deldelete
exit退出
clsclear screen
shutdowb关机指令,如一小时后自动关机,如 shutdown -s -t 3600

vs2010及其相关

1.调试
2.lib是一种文件后缀,是windows操作系统的库文件,有静态lib和动态lib两种。
静态lib:将导出的文件的声明和实现都放在lib文件中。
动态lib:相当于一个h头文件,用于支持相应的dll文件运行。
3.dll的使用,分为动态加载和静态加载。(dll动态链接库文件)
动态加载:在程序中用程序显示加载dll文件,通过函数GetProcAddress找到对应的函数地址,利用函数指针直接访问对应的函数,该方案不需要lib文件的支持。
静态加载:只加载对应的lib文件,不加载dll文件。编译只需要lib文件的支持,在运行的时候才调用dll文件函数。此处lib文件和dll文件都放在工程目录下,且需要包含对应的头文件。
4.添加库,添加头文件,添加路径等。
5.

类别windowslinux
静态库.lib.a
动态库.dll.so
编译输出可执行文件.exe无明显后缀

windows:使用静态库时只需要给.exe就可以了,若是动态库,还需要提供.dll(更改dll可以方便更新), 放在可执行文件的同级别下,因为windows首先在当前目录下查找。
vs2010使用静态库 ,需要在附加依赖项中添加lib库名称。【注意】1.包含目录 (头文件等)2. 库目录
6.动态库添加 loadlibrary方法。

SQL

一、一些SQL命令
·select -从数据库中提取数据
1.select name country from student
2.select * from student
3.select distinct country from student //返回唯一不同值
4.select * from student where country = ‘CN’ //文本字段
5.select * from student where id = 1 //数值字段
6.select * from student where age > 18 AND country = ‘CN’
7.select * from student where country = ‘CN’ OR country = ‘US’
8.select * from student order by age //升序
9.select * from student order by age desc //降序
·update -更新数据库中的数据
update student age = 20,country = ‘CN’ where name = ‘yzy’
·delete -从数据库中删除数据
1.delete * from student
2.delete * from where age = ‘16’
·insert into -向数据库中插入新数据
1.insert into student values (‘yzy’,18,‘CN’)
2.insert into student (name,country) values (‘yzy’,‘CN’)
·create database -创建数据库
·alter database -修改数据库
·create table -创建新表
·alter table -变更数据库表
·drop table -删除表
·create index -创建索引
·drop index -删除索引

二、SQL另外用法
·SLQ TOP -显示前多少项查询记录,在大型数据表中非常有用
·SQL LIKE 及其通配符
·SQL IN
select * from student where name IN (‘yzy’,‘zy’)
·SQL BETWEEN
select * from student where age between 18 AND 21
select * from student where age NOT BETWEEN 12 AND 18
select * from student where (age between 18 AND 21) AND (name IN (‘Y’,‘Z’))
·SQL 别名
select name AS N ,age AS A from student
select name AS N ,CONCAT(‘age’,‘country’) AS Info from student //合并两项一起显示
·SQL INNER JOIN
·SQL LEFT JOIN
·SQL RIGHT JOIN
·SQL FULL JOIN
·SQL UNION
select name from student UNION ALL select id from school ORDER BY id;
·SQL INTO 创建表并向其中复制数据
select * into student1 from student
select student.name into student2 from student
select student.name student.age into student3 from student
·SQL INSERT INTO SELECT 向一个已存在的表内复制数据

三、哈哈
·实际开发中可以将固定的SQL语句定义为宏。#define

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值