四、辅助工具、错误号和错误信息、环境变量

1.辅助工具

nm xxx.o/xxx.out/xxx.a/xxx.so:查看符号表,列出目标文件(.o)、可执行文件、静态库文件(.a)或动态库文件(.so)中的符号(函数名、变量及其地址等)

objdump -S xxx.o:显示二进制模块的反汇编信息

strip xxx.o/xxx.out/xxx.a/xxx.so:删除目标文件(.o)、可执行文件、静态库文件(.a)或动态库文件(.so)中的符号表和调试信息(减小文件大小,调试完后发布时用)

ldd xxx.out/xxx.so:查看可执行程序文件(.out)或动态库文件(.so)所依赖的动态库文件

2.错误号和错误信息

通过返回合法值域以外的值表示错误
int age(char const* name) {

return 1000;
}

返回指针的函数:通过返回NULL指针表示错误

不需要通过返回值输出信息的函数:返回0表示成功,返回-1表示失败。
int delete(char const* filename) {

return 0;

return -1;
}

通过错误号和错误信息表示产生错误的具体原因

方法1:
#include <errno.h> 全局整数变量:errno标识最近一次系统调用的错误。

方法2:
#include <string.h>
char* strerror(int errnum); // 根据错误号返回错误信息。

方法3(常用):
#include <stdio.h>
void perror(const char* s);
参数s可传入提示信息,不提示传NULL。打印最近错误的错误信息。

方法4:
printf函数的%m标记被替换为最近错误的错误信息

#include <stdio.h>
#include <string.h>
#include <errno.h> 
int main(void) 
{
    FILE* fp = fopen("none", "r");
    if (!fp) {
        printf("fopen: %d\n", errno);//方法1:需自己查找错误号的意思
        printf("fopen: %s\n", strerror(errno));//方法2:直接打印出来
        perror("fopen");//方法3:直接打印出来
        printf("fopen: %m\n");//方法4:直接打印出来
        return -1;
    }
    // ...
    fclose(fp);
    return 0; 
}

虽然所有的错误号都不是0,但是因为在函数执行成功的情况下错误号全局变量errno不会被清0,因此不能用errno是否为0作为函数成功失败的判断条件,是否出错还是应该根据函数的返回值来决定。
返回值 = 函数调用(…);
if (返回值表示函数调用失败) {
根据errno判断发生了什么错误
针对不同的错误提供不同的处理
}

#include <stdio.h>
#include <stdlib.h>
#include <errno.h> 
int main(void) 
{
    FILE* fp = fopen("none", "r"); //  if (errno) {
    if (!fp) {
        perror("fopen");
        return -1;
    }
    int* pi = malloc(sizeof(int)); //  if (errno) {  //这里不用errno是因为前面文件打开失败时的错误号不会置零
    if (!pi) {
        perror("malloc");
        return -1;
    }
    // ...
    free(pi);
    fclose(fp);
    return 0; 
}

3.环境变量

每个进程都有一张独立的环境变量表,其中的每个条目都是一个形如“键=值”形式的环境变量。
终端命令行(查看bash下的环境变量):env

所谓环境变量表就是一个以NULL指针结束的字符指针数组,其中的每个元素都是一个字符指针,指向一个以空字符结尾的字符串,该字符串就是形如”键=值”形式的环境变量。
全局变量:environ,是一个二级char型指针,需要自己在代码做外部声明。

#include <stdio.h>
#include <stdlib.h> 
//定义查看环境变量的函数,参数为全局变量environ 
void penv(char** env) 
{
    printf("---- 环境变量 ----\n");
    while (env && *env)//当env的一级指针和二级指针不为空时,打印环境变量
        printf("%s\n", *env++);
    printf("------------------\n"); 
} 
int main(int argc, char* argv[], char* envp[]) 
{ //main的入口参数有三个,第三个其实为env环境变量表的首地址
    extern char** environ; //外部声明拓展environ变量作用域
    printf("%p %p\n", environ, envp);//environ,envp作用一样,都接收到环境变量表的首地址
    penv(environ/*envp*/);

	return 0; 
} 

一些环境变量的操作函数(在当前进程下的env,不一定是bash下的,当前的可通过命令行./env查看)

根据环境变量名获取其值 char* getenv(char const* name);
成功返回变量名匹配的变量值,失败返回NULL。
name - 环境变量名,即等号左边的部分

添加或修改环境变量 int putenv(char* string);
成功返回0,失败返回-1。
string - 形如“键=值”形式的环境变量字符串 若其键已存在,则修改其中,若其键不存在,则添加新变量

添加或修改环境变量 int setenv(const char* name, const char* value, int overwrite);
成功返回0,失败返回-1。
name - 环境变量名,即等号左边的部分
value - 环境变量值,即等号右边的部分
overwrite -当name参数所表示的环境变量名已存在,此参数取0则保持该变量的原值不变,若此参数取非0,则将该变量的值修改为value。(即0表示不覆盖,环境变量的键名存在时不做改变;非0时,发生覆盖)

删除环境变量 int unsetenv(const char* name);
成功返回0,失败返回-1。
name - 环境变量名,即等号左边的部分

清除(当前进程中)所有环境变量 int clearenv(void);
成功返回0,失败返回-1。

#include <stdio.h>
#include <stdlib.h>

void penv(char** env) 
{
    printf("---- 环境变量 ----\n");
    while (env && *env)//当env的一级指针和二级指针不为空时,打印环境变量
        printf("%s\n", *env++);
    printf("------------------\n"); }

int main(int argc, char* argv[], char* envp[]) 
{  	//获取环境变量中HOME这个键的值
    printf("HOME=%s\n", getenv("HOME"));
    //添加或修改环境变量,若其键已存在,则修改其中,若其键不存在,则添加新变量
    if (putenv("NAME=Helpsen") == -1) {
        perror("putenv");
        return -1;
    }
    //第三个参数:0表示不覆盖,环境变量的键名存在时不做改变;非0时,发生覆盖,更改键值
    if (setenv("NAME", "HelpsenChen", 1) == -1) {
        perror("setenv");
        return -1;
    }
    //查看环境变量表,查看覆盖情况
    penv(environ);
   
    //第三个参数:0表示不覆盖,环境变量的键名存在时不做改变
    if (setenv("NAME", "ChenHelpsen", 0) == -1) {
        perror("setenv");
        return -1;
    }
    //查看环境变量表,查看覆盖情况
    penv(environ);
    //清除环境变量表中的NAME键和其值
    if (unsetenv("NAME") == -1) {
        perror("unsetenv");
        return -1;
    }
    //查看环境变量表,是否以清除NAME的键和其值
    penv(environ);
    //清除(当前进程中)所有环境变量 
    if (clearenv() == -1) {
        perror("clearenv");
        return -1;
    }
    //查看environ是否为空指针了
    printf("%p\n", environ);  	//查看环境变量表内容是否已清空
    penv(environ);
    return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值