C++编程思路

  1. 递归函数不能使用条件运算符如何结束:

    • 使用模板函数进行编程,显示定义递归结束条件时的模板:

      template <int m> inline int SumTo() { return m + SumTo<m-1>(); }  
      template <> inline int SumTo<1>() { return 1; }
      
    • 使用虚函数,使用虚函数来构造递归,在基类种定义虚函数Sum(n)返回0,通过将指针数组的两个元素分别绑定到基类和派生类,其中基类的Sum()结束递归,!!n来构造true(1) false(0)来对指针数组进行访问

    • 使用短路计算来构造递归:重点是输入0的时候输出0来结束递归

      int Sum_Solution(int n) {
              int ans = n;
              ans && (ans += Sum_Solution(n - 1));
              return ans;
          }
      
  2. C++、C混合编译问题

    extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中。提示编译器遇到此变量或函数时,在其它模块中寻找其定义,另外,extern也可用来进行链接指定。

    在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。

    extern用在变量声明中常常有这样一个作用:你要在.c文件中引用另一个文件中的一个全局的变量,那就应该放在.h中用extern来声明这个全局变量。

    实际上函数的声明和定义都不需要添加extern关键字,在实际使用的时候也最好不要添加关键字。

    如果一个函数是不会被其它文件调用的,那么这个函数应该被声明成static的。

    • 现代[编译器]一般采用按文件编译的方式,因此在编译时,各个文件中定义的[全局变量]是互相不透明的。也就是说,在编译时,全局变量的可见域限制在文件内部。在编译阶段,各个文件中定义的全局变量相互是不透明的
    • 到了链接阶段,要将各个文件的内容“合为一体”,因此,如果某些文件中定义的全局变量名相同的话,在这个时候就会出现错误,也就是上面提示的重复定义的错误。因此,各个文件中定义的全局变量名不可相同。在链接阶段,各个文件的内容(实际是编译产生的obj文件)是被合并到一起的,因而,定义于某文件内的全局变量,在链接完成后,它的可见范围被扩大到了整个程序。
    • extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”
    • 如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。
    • 在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况。C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
    • 在C++引用C语言中的函数和变量时,C++的头文件需添加extern “C”,但是在C语言中不能直接引用声明了extern “C”的该头文件,应该仅将C文件中将C++中定义的extern “C”函数声明为extern类型。

编程题目小技巧

  1. 判断一个数是偶数还是奇数,即判段该数二进制末尾是否为0:
    a%2==0或者a&0x0001==0
  2. 求一个数中1的位数:
    (1)直接逐位除10取余判断
    (2)将数字转换为字符串然后使用STL中的count方法
  3. 给定三角形ABC和一点p(x,y),如何判断点p是否在ABC内:
    根据面积法,如果p在三角形内部,那么三角形ABP面积+三角形BCP+三角形ACP的面积应该等于三角形ABC的面积。
  4. 要想编写一个函数在main函数执行前运行,就要使用constructor
     _attribute((constructor))void before(){
       printf("before main\n");
     }