昨天,看了一点《c++ primer》和《程序员的自我修养》,想起了自己以前的两个知识点,这里回顾,并且总结一下。

1. const指针的参数

  看primer的时候,看到几个概念,虽然都大概知道,但是还是有点模糊的,今天权且记在这里。

(1)const形参

  const形参,从const的意思来看,就是形参是const的,不能够改变。但是函数在传值的时候都是传的副本,所以不管形参是不是const,都可以使用const或者非const的实参传递。【注:这里指的是普通的形参】

(2)const引用避免复制

  这个是之前不理解的,在c++中,const的引用是不会发生复制行为的,这样在大类型为参数的时候,节省了复制的时间,提高了效率。

(3)非const的引用不灵活

  因为形参是非const,这样导致传进来的的参数必须是非const,从而字符串常量已经const的参数就导致编译错误了。

(4)总结

  看到这里的时候,想起以前面试的时候一道题:

  char str1[] = "string";

  char *str2 = "string";

  testfunc1(char *str1)

  testfunc2(const char*str),问下面表达式的对与错,

  *testfunc1(str1)

  *testfunc1(str2)

  *testfunc2(str1)

  *testfunc2(str2)

解释:

  str1是一个字符数值,也可以理解为c风格的字符串(针对c++),大小为7,包括最后的'\0'。

  str2是一个指向const类型的字符串的指针,大小也是7,不能修改了。

  testfunc1的形参是一个非const的字符串指针

  testfunc2的形参是一个指向const字符串的指针,在函数体能不能修改str的值。这只是表示不能在函数中对str修改。

  所以从const的意义上,我给出的答案是

  *testfunc1(str1)  Y

  *testfunc1(str2)  N 函数体内是可以修改str2的,但是str2是const,不能被修改。

  *testfunc2(str1)  Y

  *testfunc2(str2)  Y

2. 动态链接库的接口函数使用

(1)书上代码分析

  1. #include <stdio.h>
  2. #include <dlfcn.h>
  3.  
  4. #define SETUP_STACK \
  5. i = 2; \
  6. while (++i < argc - 1) { \
  7. printf("i: %d\n", i);\
  8. switch (argv[i][0]) { \
  9. case 'i': \
  10. printf("%d\n", i);\
  11. asm volatile("push %0" :: \
  12. "r"(atoi(&argv[i][1])) ); \
  13. esp += 4; \
  14. printf("%d\n", i);\
  15. break; \
  16. case 'd': \
  17. atof(&argv[i][1]); \
  18. asm volatile("subl $8, %esp\n" \
  19. "fstpl (%esp)" ); \
  20. esp += 8; \
  21. break; \
  22. case 's': \
  23. asm volatile("push %0" :: \
  24. "r"(&argv[i][1]) ); \
  25. esp += 4; \
  26. break; \
  27. default: \
  28. printf("error argument type"); \
  29. goto exit_runso; \
  30. } \
  31. printf("%d\n", i);\
  32. }
  33.  
  34. #define RESOTRE_STACK \
  35. asm volatile("add %0, %%esp"::"r"(esp))
  36.  
  37. int main(int argc, char* argv[])
  38. {
  39. void *handle;
  40. char *error;
  41. int i;
  42. int esp = 0;
  43. void *func;
  44.  
  45. handle = dlopen(argv[1], RTLD_NOW);
  46. if(0 == handle)
  47. {
  48. printf("Can't find library: %s\n", argv[1]);
  49. return -1;
  50. }
  51.  
  52. func = dlsym(handle, argv[2]);
  53. if ((error = dlerror()) != NULL)
  54. {
  55. printf("Find symbol %s error: %s\n", argv[2], error);
  56. goto exit_runso;
  57. }
  58.  
  59. switch (argv[argc - 1][0])
  60. {
  61. case 'i':
  62. {
  63. int (*func_int)() = func;
  64. SETUP_STACK;
  65. printf("%p\n", func_int);
  66. int ret = func_int();
  67. RESOTRE_STACK;
  68. printf("ret = %d\n", ret);
  69. break;
  70. }
  71. case 'd':
  72. {
  73. double (*func_double)() = func;
  74. SETUP_STACK;
  75. double ret = func_double();
  76. RESOTRE_STACK;
  77. printf("ret = %f\n", ret);
  78. break;
  79. }
  80. case 's':
  81. {
  82. char* (*func_str)() = func;
  83. SETUP_STACK;
  84. char *ret = func_str();
  85. RESOTRE_STACK;
  86. printf("ret = %s\n", ret);
  87. break;
  88. }
  89. case 'v':
  90. {
  91. void (*func_void)() = func;
  92. SETUP_STACK;
  93. func_void();
  94. RESOTRE_STACK;
  95. printf("ret = void");
  96. break;
  97. }
  98. }/* end of switch */
  99.  
  100. exit_runso:
  101. dlclose(handle);
  102. }

  后面比较简单,前面的汇编代码没怎么看懂,再研究一下。

(2)回顾自己之前的代码

  1. void prepare_start_dark(){
  2. /* 调入动态函数分析 */
  3. handle=dlopen("./lxx.so",RTLD_LAZY);//open lib file
  4. if(handle == NULL){
  5. printf("Warning: no lib file, program go on!\n");
  6. daylog_error("Warning: no lib file, program go on!\n");
  7. get_xx = get_xx_default;
  8. }
  9. else{
  10. get_xx = dlsym(handle,"get_xx");//call dlsym function
  11. }
  12. }
  13.  
  14. void prepare_end_dark(){
  15. /* */
  16. if(handle != NULL)
  17. dlclose(handle);
  18. }

  感觉之前写的还是比较正常的,唯一不一样的是用了RTLD_LASY,应该是查资料的时候,别人这样用的,就直接copy过来的。看了书之后,知道是延迟绑定,就是动态链接器启动加载的时候并不是把所有的共享对象都加载进去,而是加载一部分需要的,这样提高了程序启动时候的性能。延迟绑定就是第一次用到的时候在加载!

(3)总结

  还是有点为了学习而学习的感觉,上面的汇编代码一定要去学习看明白!

两个知识点的回顾(const指针和动态链接库函数dlopen)的更多相关文章

  1. const 指针与指向const的指针

    最近在复习C++,指针这块真的是重难点,很久了也没有去理会,今晚好好总结一下const指针,好久没有写过博客了,记录一下~ const指针的定义: const指针是指针变量的值一经初始化,就不可以改变 ...

  2. void指针和const指针

    void指针:主要是便于传递不同类型的参数 const指针: const char *p :const 在* 的左边表示指向一个常量指针:表示指向的内容不可变(*p不能变,p可以改变) int a = ...

  3. const 指针

    使用指针时要涉及两个目标,即指针本身和指针所指的对象.关于const指针变量,可归结为以下三种: 1.指向常量的指针变量: 2.常指针变量: 3.指向常量的常指针变量. 一.指向常量的指针变量:声明格 ...

  4. C++的引用与const指针的关系以及各种传递方式

    首先我们知道 const int *p 与 int const *p 是一样的,即 *p 是常量:而 int * const p 跟上面是不一样的,即 p 是常量:我们知道引用只是一个别名,与变量共享 ...

  5. 速记const 指针与指向const的指针

    指向const的指针.它的意思是指针指向的内容是不能被改动的.它有两种写法. ` const int* p; (推荐) int const* p;` 再说const指针.它的意思是指针本身的值是不能被 ...

  6. const指针与指向const的指针

    当使用带有const的指针时其实有两种意思.一种指的是你不能修改指针本身的内容,另一种指的是你不能修改指针指向的内容.听起来有点混淆一会放个例子上来就明白了.       先说指向const的指针,它 ...

  7. const指针总结

    const 总结: 假设keywordconst出如今星号左边.表示被指物是常量:即不能通过指针改动变量的值. 假设keywordconst出如今星号右边,表示指针自身是常量:即不能改变指针的指向. ...

  8. C++之常指针,指针常量,函数指针,const用法总结

    1.const char *p,char const *p,char * const p 对于C++而言,没有const * 修饰符,所以,const只可以修饰类型或者变量名.因而const char ...

  9. 函数返回值为 const 指针、const 引用

    函数返回值为 const 指针,可以使得外部在得到这个指针后,不能修改其指向的内容.返回值为 const 引用同理. class CString { private: char* str; publi ...

随机推荐

  1. 剑指offer等算法总结归类

    从数据结构分 一.链表: 3.题目描述:输入一个链表,从尾到头打印链表每个节点的值(递归) 思路:递归调用,调一次,加一次到list中 14.题目描述:输入一个链表,输出该链表中倒数第k个结点 两个指 ...

  2. (转)MySQL open_files_limit相关设置

    http://www.cnblogs.com/zhoujinyi/archive/2013/01/31/2883433.html---------------------------MySQL ope ...

  3. react&webpack使用css、less && 安装原则 --- 从根本上解决问题。

    在webpack-react项目中,css的使用对于不同人有不同的选择,早起是推荐在jsx文件中使用 css inline js的,但是这种方法要写很多对象来表示一个一个的标签,并且对于这些对象,我们 ...

  4. java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  5. 8.28_the end

    HomeWork the first level 1. 盒模型 #parent { width: 100px; height: 100px; background:black; overflow: h ...

  6. 存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20

    存储器的保护(三) 修改本章代码清单,使之可以检测1MB以上的内存空间(从地址0x0010_0000开始,不考虑高速缓存的影响).要求:对内存的读写按双字的长度进行,并在检测的同时显示已检测的内存数量 ...

  7. python 网络编程——客户端

    网络通信的基本接口是socket,它扩展了操作系统的基本I/O到网络网络通信.socket可以通过socket()函数来建立,通过connect()函数来连接.得到了socket,可以确定本地和远程端 ...

  8. 手动修改user-agent

    1. 在浏览器地址栏输入 about:config.弹出对话框:

  9. [java源码解析]对HashMap源码的分析(二)

    上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得“拉链法 ...

  10. [springBoot系列]--spring-boot-devtools在Idea中热部署方法

    1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.sprin ...