Unix C语言入门准备(二)
来源:互联网 发布:中国经济发展数据图表 编辑:程序博客网 时间:2024/04/30 18:47
一、使用程序直接调用库文件的函数
#include<dlfcn.h>
void *dlopen(const char *filename,int flag);
参数表(库文件路径,flag标记)。flag 比较常用的有两个:RTLD_LAZY 延迟加载,RTLD_NOW 立刻加载。
char *dlerror(void);
有错返回错误信息,没错返回NULL。
void *dlsym(void *handle,const char* symbol);
第一个参数为dlopen的返回值,第二个是函数名。
int dlclose(void *handle);
参数为dlopen的返回值。
最后在连接程序的时候要加选项 -ldl.(Link with -ldl ."gcc code.c -ldl")
步骤:
#include<dlfcn.h>
1.用dlopen()打开一个库文件,返回void*;
2.用dlsym()按函数名打开一个函数,返回函数指针;
3.使用函数指针;
4.用dlclose()关闭库文件;
5.dlerror函数判断是否出错。“!=NULL”出错。
#include<stdio.h>#include<dlfcn.h>int main(void){void* handler=dlopen("./libmylib.so",RTLD_NOW);//打开库文件返回void*char* error=dlerror();//判错if(error){printf("open error\n");return -1;}double (*f)(double,double);//定义函数指针f=dlsym(handler,"add2");//返回函数名error=dlerror();if(error){printf("sym error\n");return -1;}double r=f(2.0,3.0);printf("r=%lf\n",r);dlclose(handler);return 0;}
二、C程序员错误信息的处理
1.什么是错误处理?程序中有正确的分支和错误的分支,关于错误的情况如何处理,就是错误处理。错误处理的代码不影响错误是否发生。
2.C程序员处理错误的方式:(常规方式)
(1)返回-1代表错误。
a.如果-1不是函数的有效返回值,直接返回-1代表错误。
b.如果-1是函数的有效返回值,用-1代表错误,用指针取返回值。
(2)返回NULL代表错误。
一般来说,返回值是指针类型时,用NULL代表错误。
(3)不需要考虑错误处理的函数 返回void
练习:写4个函数(独立函数)
第一个函数实现求两个整数的最大值,如果相等返回错误。(b)
第二个函数返回一个0-10的随机数,如果随机数是0,返回错误。(a)
第三个函数传入一个字符串,如果是"error",返回错误,其他情况,返回"ok"(2)
第四个函数 打印传入的一个字符串(3)
#include<stdio.h>#include<time.h>#include<stdlib.h>#include<string.h>int max(int a,int b,int *pi){if(a>b)*pi=a;else if(a==b)return -1;else *pi=b;return 0;}int rand10(void){srand(time(0));int r=rand()%11;if(0==r)return -1;return r;}char* iserror(const char* s){if(0==strcmp(s,"error"))return NULL;return "OK";}void print(char* str){printf("%s\n",str);}int main(void){int x;int res=max(2,3,&x);if(res==-1){printf("error\n");return -1;}printf("max=%d\n",x);res=rand10();if(res==-1){printf("error\n");return -1;}printf("res=%d\n",res);char *ps=iserror("eror");if(ps==NULL){printf("strerror\n");return -1;}printf("%s\n",ps);print("hello");return 0;}
三、C语言中没有string,字符串用两种方式表示:
char* s1;
char s2[20];
其中,s1可以用"="赋值;s2只能用"="初始化,不能用"="赋值,s2的赋值使用strcpy函数。如果s1="aaa"(字面值),不支持strcpy()。
常用的字符串函数:
strcpy() --- 赋值
strlen() --- 取长度
strcat() --- 追加内容
strcmp() --- 比较两个字符串(通常判定字符串相同)
strncmp() --- 比较两个字符串的前n 个字符
四、C语言对错误的处理也有支持,主要是:
定义了一个全局变量errno,存储错误的编号。
定义了strerro/perror/printf("%m")三个函数转换错误编号和错误信息,后两个可以自动打印。
注:不是所有的函数都使用errno处理错误。
#include<string.h>
char *strerror(int errnum);
#include<stdio.h>
void perror(const char *s);[参数为自定义信息部分]
#include<errno.h>
const char *sys_errlist[];
int sys_nerr;
int errno;
五、环境变量和环境表在程序中的使用。
C语言中,提供了环境表变量environ存储环境变量的各种信息,类型是一个char**(字
符指针数组),需要extern。environ存储的是首地址。
【环境表:每个程序都会接收到一张环境表,是一个字符指针数组。数组以NULL作为
结束。全局变量environ保存了该数组的首地址。】
常用函数
#include <stdlib.h>
getenv 返回指向name关联的value的指针,没有返回NULL
格式:char *getenv(const char *name);
putenv 将形式为"name=value"的环境变量放入环境表
格式:int putenv(char *string);
setenv 将name设置为value,第三个参数表示是否覆盖。0不覆盖。非0,覆盖
格式:int setenv(const char *name, const char *value, int overwrite);
unsetenv 将name移除。
格式:int unsetenv(const char *name);
clearenv 清除环境表中所有项。
格式:int clearenv(void);
The clearenv() function clears the environment of all name-value pairs
and sets the value of the external variable environ to NULL.
#include<stdio.h>#include<stdlib.h>int main(int argc,char **argv,char **env){extern char **environ;printf("%p,%p\n",environ,env);char *value=getenv("LANG");printf("value=%s\n",value);putenv("VAR=ABC");printf("var=%s\n",getenv("VAR"));//ABCputenv("VAR=123");printf("var=%s\n",getenv("VAR"));//123setenv("VAR","456",0);//0,不覆盖printf("var=%s\n",getenv("VAR"));//123setenv("VAR","789",1);//1,覆盖printf("var=%s\n",getenv("VAR"));//789return 0;}
六、Unix/Linux的内存管理
1. STL - 内存自动分配和回收
|
C++ - new 分配,delete 回收
|
C - malloc分配,free 回收
|
Linux系统函数 - brk/sbrk
|
Linux系统函数 - mmap分配 / munmap回收 (用户层) ---------------------------------------------------------------
kmalloc vmalloc 等 (内核层/系统层)
2.Unix/Linux内存管理机制:
虚拟内存地址 - 在Unix/Linux中,每个进程都有0-4G的虚拟内存地址(其实就是数字)。虚拟内存地址必须映射到物理内存/硬盘文件空间上才能存储数据。如果虚拟内存地址没有映射物理内存/文件,会产生段错误/总线错误。内存分配就是把一部分虚拟内存地址和物理内存映射起来。程序员看到的都是虚拟内存地址。
其中0-3G是用户使用的,叫用户空间,3G-4G是操作系统使用的,叫内核空间。用户空间不能直接进内核空间,但可以通过系统函数(系统调用)进入内核空间。内存的分配和回收不是以一个字节作为单位,以一个内存页(4096字节 4KB)作为单位。
3.Unix/Linux的进程和程序:
程序 就是 可执行的文件(硬盘上的)
进程 就是 正在运行的程序(内存中的)
内存针对的是进程,进程的内存空间的组成:
1.代码区 - 存函数的代码,函数所在区,只读区。
2.全局区 - 存全局变量和static变量,读写区
3.bss段 - 未初始化的全局变量,在main执行前bss段,自动清零。
4.栈区 - 局部变量,函数参数,返回值等,内存自动管理
5.堆区 - 自由区,malloc new分配的内存,堆区的内存用free/delete回收,否则内存泄漏。
注:代码区附近有一个常量和字符串常量区,存常量和字符串字面值("string"),也是只读区,但是并入代码区。
- Unix C语言入门准备(二)
- Unix C语言入门准备(一)
- Linux C 入门准备
- C语言快速入门系列(二)
- c语言入门(二)进制
- 记录C语言入门学习之二
- C语言入门级教程二
- iOS开发入门 ? C语言系列二
- iOS开发入门 ? C语言系列二
- iOS开发入门 ? C语言系列二
- c语言范式编程入门二
- C语言入门参考(二)
- C语言入门参考(二)
- C语言指针入门(二)
- Unix c 入门指导
- UNIX与C语言
- Unix C (二)
- 【C语言】【unix c】数据类型
- Knockout学习篇
- 阿里巴巴笔试题目之2013.5.5号战报交流问题分析(gossip problem)
- 查看数据库对象创建脚本
- --通过session_cached_cursors 参数来减少软解析次数
- 10套华丽的 Windows 8 Metro 风格图标【2000+免费图标】
- Unix C语言入门准备(二)
- 清理c盘
- 联表查询
- Hibernate 延迟加载介绍
- Byte Order
- Linux常用缩写
- hdoj_1102Constructing Roads(最小生成树)&& poj_2485Highways
- c# vsto-格式文本内容控件自身短板
- 『精品素材』35套免费的 Web 和 Moible 素材套件《上集》