C函数和C++函数相互调用

实例解说

这个例子,示例了两点

  • C 如何调用C++对象里的函数
  • C++ 如何调用C的函数

共两个文件,test.c 和 main.cpp,代码解释如下:

在main.cpp (C++ 代码) 里定义了一个类MyMath,类里有个成员函数sum ;如何让C能调用这个c++的函数MyMath::sum呢?

即在main.cpp 中添加extern C后,声明定义一个C的函数call_MyMath_sum。在test.c 中先声明这个函数,然后通过调用call_MyMath_sum,达到调用C++ MyMath::sum的作用。

在test.c 中,定义了一个sum 的函数。如何让C++能调用这个c的函数sum呢? 这么做的,在main.cpp中 extend C 后声明它,然后在main函数中直接调用就可以了。

代码有点绕,C和C++调来调去的,不过仔细看就容易明白。

起关键作用的就是 extent C 这个关键语句,它的作用是告诉C++编译器,把后面的语句当作C语言进行处理。

代码如下

C语言中的函数,其中调用了C++中的call_MyMath_sum:

test.c

int call_MyMath_sum (int, int); // 此函数定义在main.cpp中
int sum(int a , int b) {
    return call_MyMath_sum(a,b);
}

C++语言中的函数:

main.cpp

# include <iostream>
using namespace std;
extern C { 
    int sum(int , int);  // 声明sum函数,已经在test.c 中定义过
} 

class MyMath { 
  public : 
    static int sum(int , int); 
};

int MyMath::sum(int a, int b) { 
    return (a + b); 
} 

extern C int call_MyMath_sum (int a , int b) {  // 定义call_MyMath_sum , 使其可以被c的代码调用
    return (MyMath::sum(a,b)); 
} 
int main(void) { 
    cout< <sum(5,6); return 0;  // 此sum是 在test.c中定义的
} 

如何编译:

# Makefile 
main.o:
    g++ -c -o main.o main.cpp  # 注意是g++
test.o:
    gcc -c -o test.o test.c  # 注意是gcc
main: main.o test.o
    g++ -o main main.o test.o # 最后链接用的是g++
all: main
clean:
    rm -f test.o main.o

执行 make 得到可执行文件main

[php5.2.4]explode函数不能按照”\r\n”切割字符串

php 版本 5.2.4 现有一txt文件,格式如下: file.txt  

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5

要将其内容按行分割存入数据$array中   执行代码:  

  1. $fileContent = trim(file_get_contents(‘file.txt’);
  2. $array = explode(“\r\n”, $fileContent);

并未达到预想的效果   $array => array( 0 => String(15) “1 2 3 4 5” ) 这就是问题! 解决方法:  

  1. $fileContent = trim(file_get_contents(‘file.txt’));
  2. $array = array_unique(explode(‘,’, str_replace(“\r\n”,”,”,$fileContent)));

protected函数中含有private属性,此类被继承后,此属性是否有效

答案是肯定的,以下面代码为例:

  1. < ?php
  2.  class A
  3.  {
  4.      private $var;
  5.      protected function fun()
  6.      {
  7.          $this->var = ‘Hello var!’;
  8.          echo $this->var;
  9.      }
  10.  }
  11.  class B extends A
  12.  {
  13.      public function fun0()
  14.      {
  15.          $this->fun();
  16.      }
  17.  }
  18.  $b=new B();
  19.  $b->fun0();
  20. ?>

其中,var为class A中私有变量,被protected型fun函数调用。当class A被class B继承,class B并不能继承属性var,但是class B调用fun函数时,属性var仍然是有效的。 浏览器中显示结果如下:

[plain] view plaincopy

  1. Hello var!

PHP 编程陷阱

遍历数组元素,使用引用

foreach ($PostList as &$postInfo) { 
}
unset(&$postInfo); // 最好加上这条语句,不然下面的语句中用到这个变量,用的是数组最后一个元素

运算符结合性和优先级

尽可能不写运算符堆砌的语句,可读性较差。

浮点数比较

和其他语言浮点数比较相同

不同类型数值比较

var_dump("true == 70", true == 70);
bool(true)

整形和布尔比较,PHP会先把整形转换成布尔

php 版本 5.2.4 问题:文件字符串转码时按字节截断不当 比如

$str = “公司”;                               //默认以UTF-8编码
$str = Simple_Util_String::msubstr($str, 4); // 按字节截取前4个字节,原字符串有6个字节
$str .= “adfadsfasdfadsfasdf”;          //拼接后面的字符串  (执行下一步后,这些字符就消失了)
$str = iconv("UTF-8", "GBK//TRANSLIT",$str); // 转码 , 遇到不认识的字符串进行转写

执行此步时,“公司”的“司”字编码不完整,iconv不认识,但iconv没有转写,而是做了截断。导致$str后面的字符串也没有转换成功,“adfadsfasdfadsfasdf”丢失了。在一些商业产品,尤其是有关统计的系统里,这是很危险的。 解决方法是: 改变iconv第二个参数。

$str = iconv("UTF-8","GBK//IGNORE", $str);

总结:iconv的TRANSLIT并不靠谱,遇到不认识也不能转写的字符串,也可能截断。保险的方法是用IGNORE。