2014年9月17日 | 标签:

1、打开android sdk manager

2、打开tool->options,如图所示
20140326203208656

3、将Proxy Settings 里的HTTP Proxy Server和HTTP Proxy Port分别设置成mirrors.neusoft.edu.cn和80

将Others中的Force https://…sources to be fetched using http://…复选框勾上

如下图所示:
20140326203514656

2014年8月19日 | 标签:

Linux 版本

Beyond Compare 3
Licensed to: z27315
Quantity: 9999 users
Serial number: 6155-5313
License type: Pro Edition for Linux

---BEGIN LICENSE KEY ---
nURCQNfYe7tyOXycDWmUJ1VFnSscg00JH9VDlPTsx134CbSlEqsmPOjirOJXYoImOf-ubkcF5E-vjWWUu3w8+dJzJXE6YVapYW7f+tRRXRFI4yn4NjjZ0RiiqGRCTVzwComUcXB-eiFWRBY6JpSsCNkmIxL5KsRCo442djHhTZE+
---END LICENSE KEY -----
2014年8月12日 | 标签:

中文名: 代码阅读工具
英文名: Scientific Toolworks Understand
资源格式: 压缩包
版本: v2.6.600 x86|x64<持续更新>
发行时间: 2011年
制作发行: Scientific Toolworks, Inc
语言: 英文
简介:

thumb

Understand软件的功能主要定位于代码的阅读理解。界面用Qt开发的。
具备如下特性:
1、支持多语言:Ada, C, C++, C#, Java, FORTRAN, Delphi, Jovial, and PL/M ,混合语言的project也支持
2、多平台: Windows/Linux/Solaris/HP-UX/IRIX/MAC OS X
3、代码语法高亮、代码折迭、交叉跳转、书签等基本阅读功能。
4、可以对整个project的architecture、metrics进行分析并输出报表。
5、可以对代码生成多种图(butterfly graph、call graph、called by graph、control flow graph、UML class graph等),在图上点击节点可以跳转到对应的源代码位置。
6、提供Perl API便于扩展。作图全部是用Perl插件实现的,直接读取分析好的数据库作图。
7、内置的目录和文件比较器。
8、支持project的snapshot,并能和自家的TrackBack集成便于监视project的变化。
小技巧 :
1、设置字体和颜色风格
修改默认字体:Tools – Options – Editor – Default style
修改颜色: Tools – Options – Editor – Styles
2、生成UML类图、调用树图
默认安装的插件不支持这两种图,需要从官网下载插件。
_http://www.scitools.com/perl_scripts/uperl/uml_class.upl
_http://www.scitools.com/perl_scripts/uperl/invocation.upl
放到sti/conf/scripts/local目录下。
然后重新运行,执行 project- project graphical views – xxxx可以生成这两种图。
3、更改图的字体
直接修改对应的脚本文件(\Program Files\STI\conf\scripts目录下),在do_load( )函数的对应位置加入如下的设置:
$graph- default( fontname , Consolas , node );
$graph- default( fontsize , 10 , node );
$graph- default( fontname , Consolas , edge );
$graph- default( fontsize , 10 , edge );
注意:有的脚本中的作图变量名不是 $graph 而是 $g。

IPB Imagethumb

注册码:09E58CD1FB79

2014年8月12日 | 标签:

通常登录修改提示修改两个地方即可,如下:
1、profile /etc/profile或者~/.profile、~/.bashrc (bash shell有效)
2、motd /etc/motd 如下截图是修改了profile做到的 图片:

图片看不到请戳这里

aa4ad4eb4e274e0c6654c017894faa9c

profie增加内容如下:

echo -ne "\033[0;33m"
 
cat <<EOT
 
                                  _oo0oo_
                                 088888880
                                 88" . "88
                                 (| -_- |)
                                  0\ = /0
                               ___/'---'\___
                             .' \\\\|     |// '.
                            / \\\\|||  :  |||// \\
                           /_ ||||| -:- |||||- \\
                          |   | \\\\\\  -  /// |   |
                          | \_|  ''\---/''  |_/ |
                          \  .-\__  '-'  __/-.  /
                        ___'. .'  /--.--\  '. .'___
                     ."" '<  '.___\_<|>_/___.' >'  "".
                    | | : '-  \'.;'\ _ /';.'/ - ' : | |
                    \  \ '_.   \_ __\ /__ _/   .-' /  /
                ====='-.____'.___ \_____/___.-'____.-'=====
                                  '=---='
 
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        佛祖保佑    iii    永不死机
 
EOT
 
echo -ne "\033[m"
2014年4月23日 | 标签:

这样的表格数据

转换成

处理:

上面表格的数据 copy 到 textmate 上后,显示如下:

首先替换掉『服务器端』这几个字,剩下的再次用正则替换基本上就成了

此时还会有部分空行,可以再替换一下:

 

2014年4月17日 | 标签:

转自:http://bbs.csdn.net/topics/390099608

关于C语言声明、指针、数组、函数、typedef等等的一通“超级扯”

按:在CSDN论坛上,有坛友这样提议:

typedef int (*PF)();
应该被写作:
typedef int (*)() PF;
才是“严谨”、“合乎逻辑”的。

对此,我来说说吧……

typedef 关键字的意思是“关于类型的定义”。

为什么要有“类型”这个观念?

我们都知道,在计算机的内部,一切数据和功能性代码(比如函数、命令、指令等)都是以0、1组成的有序排列来进行存储和运算等处理的。所以,我们总是会这麽说:“计算机只认得‘二进制’”。

在C编程语境中,当我们写下:

int a;

的时候,实际上是在告诉编译器这位老Boss:请您为我的程序在存储器中预留一块地方,这块地方不论将来会存储什么样的东东,您一律把那些东东视作“整数”来处理。

老Boss根据自己所在的计算机架构或操作系统环境,确定1个“整数”需要在存储器里面占有多大的地盘。而我们经常使用的架构或环境,决定了,这块地盘的大小,通常是4Bytes即32bits。

而“a”这个符号,是我们的程序用来称呼那块地盘的代号。也就是说,在我们的程序中,将来凡是用到了“a”这个符号,就是在告诉老Boss:我是让您在那 块地盘上做些什么,如读取那里的数据(当a作为右值),或向那里刷入什么数据(当a作为左值)。当然,这所有的处理,均是把那块地盘上既有的数据或将要刷 入的数据,作为“整数”来看待。

以上这一切,就叫做“定义性声明(defining declaration)”,我们可以根据不致引起歧义的某种习惯,简称它为“定义”或“声明”。(严格地说,变量的定义与声明,两个概念之间,有一些微妙的联系与区别,在此不再赘述。)

C语言采用了不同于其他语言的规则,来让程序员进行这种声明工作。

作为比较,我们可以观察在Ada语言中,类似的工作,是如何进行的:

a:integer;

就这个简单的例子看来,我们除了看到Ada语言似乎利用了一种更加接近人类语言习惯的规则(语序以及冒号)之外,与C还是大同小异的,但是,后面所讲到的例子,就会把这种特性上的差异,扩大地展现出来。

此外,我们也不难意识到,C的这个规则,会跟基于对象(Object-Based)的某些思路,有一些“暗合”的地方,比如说:

当我们利用class SomeClass{… …};来定义一个类之后,我们可以利用

SomeClass AnObject;

来将SomeClass这个类实例化出来一个具体的对象,即 AnObject。

我们已经了解到,SomeClass其实是对AnObject与其他具有相同“结构”的实例们的一种抽象。那么,我们可以反过来推:

int a;

就可以用“变量a其实是int这个‘类’的一个实例化”这样的思路,来揣度(仅仅是一种类比性思维)C语言中声明变量的这件事情。

以上这些,都是比较容易理解的。但是C语言不会就这麽轻易地放过我们。

在C语言编程语境中,把一个“符号”的“类型”或“性质”表达出来,有远比“类型名 变量名”更为复杂的方式。比如:

char a[n];

在这个例子中,引入了方括号。围绕符号“a”的事情就复杂了一层。方括号紧跟在符号“a”的右边,说明符号“a”是用来称呼一段连续分布在存储器中的多个 数据,俗称“数组”。而这一段数据中的单位数据,即每个元素的“类型”是char,且所有元素均被视为char类型,概莫能外!

“类型名 变量名”的简单做法,已经失效了。在C中,我们不能用

char array a;

array_of_char a;

这样的写法来声明一个元素均为char类型的数组。

但是,在Ada语言的规则里,就可以这麽写:

a : array (1..n) of  Integer;

在C语言的“侄子”——Perl语言中,用“@”来声明一个数组:

@a=(value_alpha..value_omega);

而在C语言中,即没有array关键字,也没有用来声明数组的@符号,甚至C语言本身都不会对数组元素的下标是否越界做出令程序员知晓正误的判 断 —— 这一切,不得不让我狗胆包天地,下了这个狂妄的断言:“在C语言中,压根儿就没有‘数组’这个东东!”(哎哟——一只鞋子袭来!)

不那么狂了,把话说回来:在C语言中,通过引入方括号,来声明一个数组。注意,这个方括号对,与用“数组名[下标]”的写法来指明具体某个元素这种方法里的方括号对,是完全不同的。

在指明(术语叫“引用”)数组中某个元素的时候,也是用方括号对。这里的方括号对,叫做“取下标操作符”。其实“取下标操作符”是一种被包装起来的指针运 算符,即一种存储器上的偏移量运算,所以,我们可以大胆猜测:在C语言中,这种利用方括号对来引用数组中某个元素的做法,应该是承袭于某些更加低级的(更 加接近计算机存储机制底层的)语言。

这是C语言承袭老语言的一方面,那么,C语言在其内部扩展的一方面,就是把方括号对,作为数组声明的一个符号。

当“*”——这个邪恶的星号,被C语言引进来了之后,关于声明的事情,就变得更加复杂和诡异了。比如:

char *a[n];

我们如果把星号看成一个“读取指针所指向的存储器某个位置上的数据”的符号,又顽固地抱持着以“类型名 变量名”来解读声明的这种思路的时候,上面这行语句,就彻底无解了 —— 详述如下:

如果星号与a先结合构成一个意群,那么,该语句的意思就是:读取指针变量a所指向的位置上的数据,然后这个数据……数组……完全说不通了!

如果a与方括号对先结合构成一个意群,那么,该语句的意思就是:一个名叫a的数组成为一个指针,该指针指向一个类型为char的数据……可是,一个数组(即多个元素组成的序列)能成为一个指针吗?这同样也是不可想象的事情。

乱猜是没有结果的。我们必须用C语言自己的规定,来解读和运用这种写法。合乎C语言规定的思路是:

符号a先与紧跟其后的方括号对结合,显明了a是指代一个数组。而数组的每一个元素,都是一个指针变量,这些指针变量乃均为指向某些char类型的数据之用。

根据上述思路,该行语句可写为:

char* a[n];

即char与星号先结合,构成一个意群,我们且以Ptr2Char代之。那么,该行语句即恒等变换为:

Ptr2Char a[n];

与“char* a[n];”比较,解读思路是一致的,即,一切放在“a[n]”顶头的东东,均指明了数组里每个元素的类型。(不妨强迫自己这样记住:数组是没有类型的,数组只是一段连续分布在存储器中的数据而已,而这些单位数据即元素,是有类型的。)

当我们讨论到这里,就可以把关于typedef的概念自然地引入了。

我在上面说到,char可以与星号先结合构成一个意群,且可以用Ptr2Char这个新符号代表它,那么,typedef关键字就可以登场了:

typedef int* Ptr2Char;

Ptr2Char a[n];

在这里,不妨这样理解typedef的用途,它把“int*”打了包,取名为“Ptr2Char”(即所谓“别名”),注意,这个别名不是变量名,而是类 型名。由于“Ptr2Char”是一个类型名,所以,“Ptr2Char”可以被用来声明该类型的变量(或者由一群该类型的变量构成的数组)。

我们依然可以用“类 vs 对象(实例化)”的类比性思路,来理解这个过程:

在第一行里,“int*”是一个抽象,“Ptr2Char”是该抽象的一个实例化;

在第二行里,“Ptr2Char”是一个抽象,“a[n]”这个数组里的每个元素,分别都是该抽象的一个实例化(一共有n个实例化)。

之所以,我们依然可以用“类 vs 对象”这个类比性思路,必须有一个前提,那就是:“typedef T S”中的T与S之间不是(由T到S的)单射关系,而是可以是“一对多”的。也就是说:

typedef int* Ptr2Char_A;
typedef int* Ptr2Char_B;
Ptr2Char_A a[n];
Ptr2Char_B b[n];

是正确的。

既然,我们可以用“类 vs 对象”的类比性思路,来理解typedef,如同理解“数据类型名 变量名”一样,那么,为什么下面这样写就是错误的呢?

int* Ptr2Char;

Ptr2Char a[n];

在上面的第一行代码中, Ptr2Char是“int*”这个类型抽象的一个实例化出来的变量。而只有用了typedef关键字,才能让“int*”这个类型抽象实例化出来一个类型,而后者又是实例化的变量的一个抽象。

接下来,我们回到“char *a[n];”这个例子。

上面说了,由于把星号、方括号引入了对于符号的声明,使得C语言的声明方法,变得特别复杂,甚至非常晦涩。

我们之所以感到“char *a[n];”这样的声明很复杂,可能有以下几点原因:

第一,我们对声明的客体,即“我们到底是为谁而声明?”这个问题,回答起来,不是那么有底气。

第二,即便是知道了我们为谁而声明,我们也不知道这个东东的“性质”到底是个啥?整数?字符?指针(又是指向另外某一个谁的)?还是函数?

我们必须要做出明确的解答:

对于第一个原因中的问题,答案是:声明的客体,是该声明中出现的唯一的一个“不明确”的符号。所谓“明确的”,就是已经被定义 、声明、初始化的。比如在

char *a[n];

里面,其中的n一定是被事先定义 、声明、初始化了的。“char”是关键字,星号和方括号以及句尾的分号均是语言的保留部分。那么,唯一的一个“不明确”的符号,就是“a”。所以,我们可以放心大胆地认定:整个语句的声明客体是符号“a”,即我们是为“a”而声明。

对于第二个原因中的问题,就是难点了。符号“a”是被其他的“已明确的”符号、星号、方括号、各种关键字所层层包围或粘黏起来的,而不像Ada语言中的那么明显(符号被清晰地放在冒号的左边)。

—— 这就是C语言的特色了:

———— 一个符号的“性质”,由它所出现的位置,即它的处境、它被什么样的东东(按什么样的次序)所包围或粘黏,来决定!

根据我很浅薄的观察和很笨拙的思考,得出一些结论,希望能对大家有所帮助:

(1)在声明中,符号出现在方括号的左边,符号的性质一定是:指代一个数组,即作为数组名。

(2)在声明中,符号出现在圆括号的左边,符号的性质一定是:指代一个函数,即作为函数名。

(3)在声明中,符号出现在星号的右边,符号的性质一定是:它跟右边所构成的整体的其中之元素(在情况(1)下)或返回值(在情况(2)下)是指针,且指针所指向的数据之类型,一定由星号左边的关键字来确定。

根据以上结论所确定的原则,我们就不难解读“char *a[n];”。

既然可以根据上述的原则,来解读“数据类型名 变量名或混杂的东西”这种声明,也就可以利用这些原则,来解读typedef语句。我们可以把

typedef int* Ptr2Char;

Ptr2Char a[n];

改写成:

typedef int* Ptr2Char[n];

Ptr2Char a;

上下两段代码,是完全等效的!!

请看, 在typedef 语句中,“Ptr2Char”这个符号被夹在了星号与方括号当中,但是这个符号的意义完全没有失真。

这就是C语言的声明规则以及typedef的用法,所体现出的它的特色。你说它晦涩也好,说它变态也好,甚至说它有缺陷、有陷阱也好…… 但是,它保持了高度的逻辑性、可理喻性,以及由此带来的高度的可扩展性。

我在上面,曾经说过“在计算机的内部,一切数据和功能性代码(比如函数、命令、指令等)都是以0、1组成的有序排列来进行存储和运算等处理的。”

所有前面所讲述的,都是关于数据,即变量、由连续存储的变量所构成的数组,它们在存储器中的存在形态,均是0和1构成的序列。由于这些序列在存储器中都有 确定的位置,所以,指针这个机制的存在,就有了确定性的基础,也就是说,C语言可以允许我们利用指针,来操控(指代、指向、引用、解引用、读取、刷入)这 些分布在存储器中各个位置上的数据。

那么,功能性代码,也是如此。我们的程序赖以运行的最基本结构——函数,也是以0和1所构成的序列,于存储器中存在的。而我们又知道“计算机只认得‘二进 制’”,那么,从这个角度上说,不论是数据,还是函数,在计算机内部那头看来,都是一样的东西,计算机本身是“无法区分”数据和函数的 —— 这就是黑客 的基本原理之一。

也就是说,我们同样也可以利用指针,来操控(指代、指向、引用、解引用、读取、刷入)函数。所以,在C语言中,存在着这麽一些指针变量,它们所指向的,是某个函数,更具体地说,它们分别指向了某些函数可以被切入运行的那个“入口”。

接下来,我们要注意到一个事实。在C语言中,对于函数的声明,并没有用到一个类似于“function”这样的关键字。

function foo();

上面的这种写法,是JavaScript中的。而且,在JavaScript中,这样的写法,实际上,是在显式地为“function”这个类,实例化出 一个名叫foo的对象!也就是说, 在JavaScript中,一切函数,均是“function”这个类实例化出来的对象。

那么,在C语言中,是怎么声明函数的呢?

在C语言中的函数,与数学上的函数一样,有三个要素:定义域(输入)、对应法则(加工处理输入用以将来输出)、值域(输出)。

具体地说,在C语言的函数的三要素中:输入部分,即是函数的参数; 对应法则,即是函数体所实现的功能;输出部分,即是函数的返回值。

对于参数部分,必须确定一个或多个参数中每个参数的数据类型;对于返回值部分,返回值只能是以一个整体的单元而存在,那么就必须确定该单元的数据类型;对于函数体部分,在声明中,则不必和盘托出,在声明之后,自然须要写明(定义)。

所以,对于函数的声明,只要包含了关于对于参数部分的声明、对于返回值部分的声明,当然还有声明的客体,即函数名,就完备了。

上述三者,必须按次写出,如下:

返回值类型 函数名(关于参数的声明);

函数体即实现函数内在功能的部分,属于函数的定义,不在函数声明的范围之内。上述这个声明的规范,在ANSI C中,叫做“函数原型”。

再援引之前的例子,

char* a[n];

当这里的数组a,是由一个函数的返回值来确定的时候,比如是由foo这个函数的返回值来确定,那么,代码就应该是:

char* (foo())[n];

但是,很遗憾,上面这种写法是错误的。逻辑上并没有错,只是C语言中有一条硬性的规定:函数不能返回一个数组,即函数的返回值,不能是一个数组。上面的写法,会使得编译器报错:

error: ‘foo’ declared as function returning an array

不过,C语言允许函数返回一个指向任何数据类型的变量或数据结构的指针。那么,指针当然可以被用来指向一个数组。所以,我们若想利用函数的返回值来确定一个数组,可以令函数返回一个指向该数组的指针 —— 用这种“迂回曲折”的方式,来实现我们的意图。也就是:

char* (*foo())[n];

根据之前已经提到的原则: foo后面紧跟圆括号,那么foo首先圆括号结合,foo这个符号一定是用来指代函数,即作为函数名;后来,这个函数整体的左 边紧贴着星号,意思是,该函数的返回值,是一个指针;这个指针作为一个整体被夹在一个圆括号里面,后面又紧跟着一个方括号,那么,该整体是用来确定(其实 不是直接确定,而是“指向”)一个数组,由于是利用指针指向数组,而不是直接确定数组,所以,这样做的话,跟用数组名符号(如上面的“a”)来指代数组, 还是有一些微妙的区别。

顺别说一句,在这个函数的定义里,按照我们例子的意图,返回语句必须是:

return &a;

如果写成“return a;”,也可以编译通过,但是老Boss会骂一声,之后运行结果无异。

我们之前一开始介绍函数的时候,提到了,可以用指针来操控函数,也就是说,我们可以用一个指针,来指向某个函数。那么,现在我们用ptr2foo这个指针变量来指向foo这个函数。既然是声明指针变量,那么它左边所紧贴的,一定是星号。于是,代码就应该是:

char* (*(*ptr2foo)())[n];

如果要解读的话,还是老规矩:在ptr2foo这个符号所在的圆括号里面,该符号右边无东东,那么直接先跟左边的星号结合,表示该符号所指代的,一定是一个指针。然后,整个这个圆括号就跟之前的 foo这个函数名等效。

显然,在这一切的例子中,foo这个函数,是没有参数的 —— 在原型中,最好写成foo(void)以警醒自己。现在,我们有这麽一个函数叫bar,它 跟foo干的事情差不多,但是它有一个参数,其类型为int。类似上面的,ptr2bar是指向函数bar的一个指针变量。那么,关于bar这个函数的代 码,如下:

char* (*(*ptr2bar)(int))[n];

如果bar函数的参数,不是一个int类型的数据,而是一个指向int类型的数据的指针的话,代码就应该是这样的:

char* (*(*ptr2bar)(int *))[n];

怎么样?如果再让const、volatile什么的关键字穿插其中的话,那么,上述代码,假若作为考试题(考察ptr2bar 到底是个什么性质的东 东)的话,也算是一道很厉害的难题了。(其实遇到const、volatile关键字,也不要怕!规则也非常简单:(i)如果它们的左边没有星号的话,那 么它们就跟紧邻的关键字结合;(ii)如果它们的左边紧贴星号的话,那么它们就立即先与星号结合了再说,表示星号(再)右边的符号所指代的指针,是“坚贞 不屈”的。)

之前还提到:在C语言中,一个符号的“性质”,由它所出现的位置,即它的处境、它被什么样的东东(按什么样的次序)所包围或粘黏,来决定 —— 那么,这 个 ptr2bar被一层层的星号、圆括号、方括号、关键字等等所围绕和粘黏,但是,由于这些星号、圆括号、方括号、关键字等等是按着某种“次序”排列 的,所以,ptr2bar的“性质”,就在这种“次序”的存在方式中,得到了确定,而永远不会失真和发生歧义。

所以,我们可以把ptr2bar抽象出来,用typedef来“打包”,代码如下:

typedef char* (*(*P2FB)(int *))[n];

这也就是:P2FB作为一切跟ptr2bar指针具有相同性质的指针的一个抽象。如果要将这个抽象实例化的话,就这样写:

P2FB ptr2bar_obj = bar; //bar函数的指针。

如果我们在此前,已经把“int *”用typedef打包为“P2I”的话,那么,上述声明就可以分解地写为:

typedef int * P2I;

typedef char* (*(*P2FB)(P2I))[n];

上述两行代码,实际上是对应了下面这个最初的复杂的声明:

char* (*(*ptr2bar)(int *))[n];; //合乎C规范的声明。

现在,我们要把“int *”类型抽离出来,我们只抽离“int *”它一个,那么,按照那位坛友的设想,可以写作:

typedef char* (*(*ptr2bar)())[n] P2I;

但是,恐怕连那位坛友也肯定同意:这样写没有任何意义!因为“P2I”到底是什么?没有任何合理的信息。所以,只能通过“typedef int * P2I;”把“P2I”定义出来。

那么,在“typedef int * P2I;”之后,我们就可以这样声明:

char* (*(*ptr2bar)(P2I))[n];

现在,我们想要把“ptr2bar”抽离出来,那么,按照那位坛友的设想,可以写作:

typedef char* (*(*)(P2I))[n] P2FB;

那位坛友一定会说“P2FB”必然是第三个星号要修饰的东东,这是按照那位坛友所发明的新规则;我说,我也可以发明一个新规则,即typedef可以重新定义已经被定义过的类型。

在合乎C语言固有规范的情况下,加上我的这个“新发明”,不会发生冲突(总是对最早被定义的符号[没有被定义的符号视为无穷久远]按照最后一次的定义为准);但是,在那位坛友的“新规则”下,我的这个“新发明”就会引起麻烦:

typedef所定义的类型,可以是任何数据类型。(规则1,C语言规范所固有的)

比如,我完全可以这样做:

typedef char P2FB;

现在,我期望“typedef char* (*(*)(P2I))[n] P2FB;”这行语句,根据那位坛友的“新规则”来对 P2FB进行重新的定义,即期望它只是指向函数的指针的一个抽象。

但是,我不一定就把P2FB安插在第三个星号的右边,我完全可以把它安插在第三个星号的左边,因为“(char *)(…)”的写法,无论如何,都是合法的,而且根据规则1,这完全成立。

那么,“typedef char* (*(*)(P2I))[n] P2FB;”就成了:

typedef char* (*(P2FB*)(P2I))[n];

这时候,这行代码的意思就是:

typedef char* (*(char*)(P2I))[n];

如果我之前并没有将P2I设置为某个类型的别名,而是将它声明为一个整数类型的变量并且将其初始化为0的话,“(char*)(P2I)”就变成了(char *)(0),这将导致得到一个(nil)指针,即什么也不指向的指针。

这个什么也不指向的指针,作为指向char* a[n]这个数组(即数组a)的指针,结果就得到一个完全不存在的数组。

那么,我原本期望通过“typedef char* (*(*)(P2I))[n] P2FB;”这行语句所达到的目的,结果会变成啥?

typedef语句不一定为我重新定义了P2FB,而是有可能将n这个符号重定义了:n由原来的某个整数被重新定义为一个根本不存在的数组的元素数量所属于的数据类型,它好像除数为0的商数一样诡异。

…… 我兜了这麽大的圈子,使了这麽多的“坏招”,其实,就是希望那位坛友明白一点:

在C语言中,一个符号的“性质”,由它所出现的位置,即它的处境、它被什么样的东东(按什么样的次序)所包围或粘黏,来决定!

—— 这是最严谨、最符合逻辑、也是最经济地声明一个符号的方式了!

以上超“扯”了一通,仅供参考!

有什么错误,希望各位大虾拍砖指正!谢谢!

2014年4月10日 | 标签:

openwrt 不是使用的 openssh,而是一个dropbear

一、无密码登录

  1.  scp ~/.ssh/id_rsa.pub root@xxx.xx.x.x:/etc/dropbear/authorized_keys
  2. 登录到 openwrt,执行 chmod 600 /etc/dropbear/authorized_keys
  3. 从 openwrt退出,再执行 ssh root@xxx.xx.x.x 看看是否不需要密码了。

二、修改默认的22端口

同样,配置文件不在/etc/ssh下,而是/etc/config/dropbear

vim /etc/config/dropbear

修改 option Port         ’22’  为 8922

保存重启 /etc/init.d/dropbear restart

再次登录需要 ssh root@xxx.xx.x.x -p 8922

 

2014年4月10日 | 标签:

天朝 mirrors 同步不及时,导致使用 brew一直不能成功更新。

netstutekiMacBook-Pro:~ netstu$ brew upgrade
==> Upgrading 3 outdated packages, with result:
php55-mcrypt 5.5.11, vim 7.4.253, wget 1.15_1
==> Upgrading php55-mcrypt
==> Downloading http://www.php.net/get/php-5.5.11.tar.bz2/from/this/mirror
Already downloaded: /Library/Caches/Homebrew/php55-mcrypt-5.5.11
Error: SHA256 mismatch
Expected: 60e14c255f2a461a7a26639b84a2fc448cc2f91c8dead0e9fd00cd8ba27a2e96
Actual: 0d9438c2557db5809f4232148ca1567516e7ece9bf8726853ceac4a111cb8690
Archive: /Library/Caches/Homebrew/php55-mcrypt-5.5.11
To retry an incomplete download, remove the file above.

解决办法:

vim /usr/local/Library/Taps/josegonzalez-php/Formula/abstract-php-version.rb

在第60行,把PHP_SRC_TARBALL = ‘http://www.php.net/get/php-5.5.11.tar.bz2/from/this/mirror’ 修改为 PHP_SRC_TARBALL = ‘http://uk1.php.net/get/php-5.5.11.tar.bz2/from/this/mirror’

2014年4月9日 | 标签:

请先阅读此篇官方文章 http://www.php.net/manual/zh/internals2.buildsys.configunix.php

一个默认的示例:

netstutekiMacBook-Pro:extdemo netstu$ more config.m4
dnl $Id$
dnl config.m4 for extension extdemo

dnl Comments in this file start with the string 'dnl'.
dnl Remove where necessary. This file will not work
dnl without editing.

dnl If your extension references something external, use with:

dnl PHP_ARG_WITH(extdemo, for extdemo support,
dnl Make sure that the comment is aligned:
dnl [  --with-extdemo             Include extdemo support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(extdemo, whether to enable extdemo support,
dnl Make sure that the comment is aligned:
dnl [  --enable-extdemo           Enable extdemo support])

if test "$PHP_EXTDEMO" != "no"; then
  dnl Write more examples of tests here...

  dnl # --with-extdemo -> check with-path
  dnl SEARCH_PATH="/usr/local /usr"     # you might want to change this
  dnl SEARCH_FOR="/include/extdemo.h"  # you most likely want to change this
  dnl if test -r $PHP_EXTDEMO/$SEARCH_FOR; then # path given as parameter
  dnl   EXTDEMO_DIR=$PHP_EXTDEMO
  dnl else # search default path list
  dnl   AC_MSG_CHECKING([for extdemo files in default path])
  dnl   for i in $SEARCH_PATH ; do
  dnl     if test -r $i/$SEARCH_FOR; then
  dnl       EXTDEMO_DIR=$i
  dnl       AC_MSG_RESULT(found in $i)
  dnl     fi
  dnl   done
  dnl fi
  dnl
  dnl if test -z "$EXTDEMO_DIR"; then
  dnl   AC_MSG_RESULT([not found])
  dnl   AC_MSG_ERROR([Please reinstall the extdemo distribution])
  dnl fi

  dnl # --with-extdemo -> add include path
  dnl PHP_ADD_INCLUDE($EXTDEMO_DIR/include)

  dnl # --with-extdemo -> check for lib and symbol presence
  dnl LIBNAME=extdemo # you may want to change this
  dnl LIBSYMBOL=extdemo # you most likely want to change this

  dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  dnl [
  dnl   PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $EXTDEMO_DIR/lib, EXTDEMO_SHARED_LIBADD)
  dnl   AC_DEFINE(HAVE_EXTDEMOLIB,1,[ ])
  dnl ],[
  dnl   AC_MSG_ERROR([wrong extdemo lib version or lib not found])
  dnl ],[
  dnl   -L$EXTDEMO_DIR/lib -lm
  dnl ])
  dnl
  dnl PHP_SUBST(EXTDEMO_SHARED_LIBADD)

  PHP_NEW_EXTENSION(extdemo, extdemo.c, $ext_shared)
fi

config.m4文件有几个重要的宏命令如下:

* dnl 是注释;
* PHP_ARG_WITH 或者 PHP_ARG_ENABLE 指定了PHP扩展模块的工作方式,前者意味着不需要第三方库,后者正好相反;
* PHP_REQUIRE_CXX 用于指定这个扩展用到了C++;
* PHP_ADD_INCLUDE 指定PHP扩展模块用到的头文件目录;
* PHP_CHECK_LIBRARY 指定PHP扩展模块PHP_ADD_LIBRARY_WITH_PATH定义以及库连接错误信息等;
* PHP_ADD_LIBRARY(stdc++,””,EXTERN_NAME_LIBADD)用于将标准C++库链接进入扩展
* PHP_SUBST(EXTERN_NAME_SHARED_LIBADD) 用于说明这个扩展编译成动态链接库的形式;
* PHP_NEW_EXTENSION 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开;

再看看 mysql 的 config.m4

netstutekiMacBook-Pro:extdemo netstu$ more ../mysql/config.m4
dnl
dnl $Id$
dnl

AC_DEFUN([MYSQL_LIB_CHK], [
  str="$MYSQL_DIR/$1/lib$MYSQL_LIBNAME.*"
  for j in `echo $str`; do
    if test -r $j; then
      MYSQL_LIB_DIR=$MYSQL_DIR/$1
      break 2
    fi
  done
])

AC_DEFUN([PHP_MYSQL_SOCKET_SEARCH], [
  for i in  \
    /var/run/mysqld/mysqld.sock \
    /var/tmp/mysql.sock \
    /var/run/mysql/mysql.sock \
    /var/lib/mysql/mysql.sock \
    /var/mysql/mysql.sock \
    /usr/local/mysql/var/mysql.sock \
    /Private/tmp/mysql.sock \
    /private/tmp/mysql.sock \
    /tmp/mysql.sock \
  ; do
    if test -r $i; then
      MYSQL_SOCK=$i
      break 2
    fi
  done

  if test -n "$MYSQL_SOCK"; then
    AC_DEFINE_UNQUOTED(PHP_MYSQL_UNIX_SOCK_ADDR, "$MYSQL_SOCK", [ ])
    AC_MSG_RESULT([$MYSQL_SOCK])
  else
    AC_MSG_RESULT([no])
  fi
])

PHP_ARG_WITH(mysql, for MySQL support,
[  --with-mysql[=DIR]        Include MySQL support.  DIR is the MySQL base
                          directory, if no DIR is passed or the value is
                          mysqlnd the MySQL native driver will be used])

PHP_ARG_WITH(mysql-sock, for specified location of the MySQL UNIX socket,
[  --with-mysql-sock[=SOCKPATH]
                          MySQL/MySQLi/PDO_MYSQL: Location of the MySQL unix socket pointer.
                          If unspecified, the default locations are searched], no, no)

if test -z "$PHP_ZLIB_DIR"; then
  PHP_ARG_WITH(zlib-dir, for the location of libz,
  [  --with-zlib-dir[=DIR]     MySQL: Set the path to libz install prefix], no, no)
fi

if test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL" = "mysqlnd"; then
  dnl enables build of mysqnd library
  PHP_MYSQLND_ENABLED=yes

elif test "$PHP_MYSQL" != "no"; then
  MYSQL_DIR=
  MYSQL_INC_DIR=

  if test -r $PHP_MYSQL/include/mysql/mysql.h; then
    MYSQL_DIR=$PHP_MYSQL
    MYSQL_INC_DIR=$PHP_MYSQL/include/mysql
    break
  elif test -r $PHP_MYSQL/include/mysql.h; then
    MYSQL_DIR=$PHP_MYSQL
    MYSQL_INC_DIR=$PHP_MYSQL/include
    break
  fi

  if test -z "$MYSQL_DIR"; then
    AC_MSG_ERROR([Cannot find MySQL header files under $PHP_MYSQL.
Note that the MySQL client library is not bundled anymore!])
  fi

  if test "$enable_maintainer_zts" = "yes"; then
    MYSQL_LIBNAME=mysqlclient_r
  else
    MYSQL_LIBNAME=mysqlclient
  fi
  case $host_alias in
    *netware*[)]
      MYSQL_LIBNAME=mysql
      ;;
  esac

  dnl for compat with PHP 4 build system
  if test -z "$PHP_LIBDIR"; then
    PHP_LIBDIR=lib
  fi

  for i in $PHP_LIBDIR $PHP_LIBDIR/mysql; do
    MYSQL_LIB_CHK($i)
  done

  if test -z "$MYSQL_LIB_DIR"; then
    MYSQL_LIB_CHK(lib/x86_64-linux-gnu)
  fi
  if test -z "$MYSQL_LIB_DIR"; then
    MYSQL_LIB_CHK(lib/i386-linux-gnu)
  fi

  if test -z "$MYSQL_LIB_DIR"; then
    AC_MSG_ERROR([Cannot find lib$MYSQL_LIBNAME under $MYSQL_DIR.
Note that the MySQL client library is not bundled anymore!])
  fi

  PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_close, [ ],
  [
    if test "$PHP_ZLIB_DIR" != "no"; then
      PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, MYSQL_SHARED_LIBADD)
      PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_error, [], [
        AC_MSG_ERROR([mysql configure failed. Please check config.log for more information.])
      ], [
        -L$PHP_ZLIB_DIR/$PHP_LIBDIR -L$MYSQL_LIB_DIR
      ])
      MYSQL_LIBS="-L$PHP_ZLIB_DIR/$PHP_LIBDIR -lz"
    else
      PHP_ADD_LIBRARY(z,, MYSQL_SHARED_LIBADD)
      PHP_CHECK_LIBRARY($MYSQL_LIBNAME, mysql_errno, [], [
        AC_MSG_ERROR([Try adding --with-zlib-dir=<DIR>. Please check config.log for more information.])
      ], [
        -L$MYSQL_LIB_DIR
      ])
      MYSQL_LIBS="-lz"
    fi
  ], [
    -L$MYSQL_LIB_DIR
  ])

  PHP_ADD_LIBRARY_WITH_PATH($MYSQL_LIBNAME, $MYSQL_LIB_DIR, MYSQL_SHARED_LIBADD)
  PHP_ADD_INCLUDE($MYSQL_INC_DIR)

  MYSQL_MODULE_TYPE=external
  MYSQL_LIBS="-L$MYSQL_LIB_DIR -l$MYSQL_LIBNAME $MYSQL_LIBS"
  MYSQL_INCLUDE=-I$MYSQL_INC_DIR

  PHP_SUBST_OLD(MYSQL_MODULE_TYPE)
  PHP_SUBST_OLD(MYSQL_LIBS)
  PHP_SUBST_OLD(MYSQL_INCLUDE)
fi

dnl Enable extension
if test "$PHP_MYSQL" != "no"; then
  AC_MSG_CHECKING([for MySQL UNIX socket location])
  if test "$PHP_MYSQL_SOCK" != "no" && test "$PHP_MYSQL_SOCK" != "yes"; then
    MYSQL_SOCK=$PHP_MYSQL_SOCK
    AC_DEFINE_UNQUOTED(PHP_MYSQL_UNIX_SOCK_ADDR, "$MYSQL_SOCK", [ ])
    AC_MSG_RESULT([$MYSQL_SOCK])
  elif test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL_SOCK" = "yes"; then
    PHP_MYSQL_SOCKET_SEARCH
  else
    AC_MSG_RESULT([no])
  fi

  AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL])
  PHP_NEW_EXTENSION(mysql, php_mysql.c, $ext_shared)
  PHP_SUBST(MYSQL_SHARED_LIBADD)

  if test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL" = "mysqlnd"; then
    PHP_ADD_EXTENSION_DEP(mysql, mysqlnd)
    AC_DEFINE([MYSQL_USE_MYSQLND], 1, [Whether mysqlnd is enabled])
  fi
fi

参考文档:http://jasonyu.cn/html/2009/90.html

2014年4月9日 | 标签:

ext_skel 脚本其实就是一个 普通的shell 脚本,当然用其他任何语言都可以写出同样功能的脚本。

通过查看 ext_skel 脚本可以得知,它会自动生成目录以及整个扩展的架子出来。

要怎么做才能开始创建扩展呢?首先要下载一份 PHP 的源码。

使用 git 的方式:

git clone https://github.com/php/php-src.git

或者直接到官方下载 tar 包解压。

下载后,进入 php-src/ext 目录,ext_skel 就存在这个目录下。

下面我们就执行一下看看输出什么结果.

直接执行不加任何参数,会输出相关参数,输出结果如下:

netstutekiMacBook-Pro:ext netstu$ ./ext_skel
./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]
           [--skel=dir] [--full-xml] [--no-help]

  --extname=module   module is the name of your extension
  --proto=file       file contains prototypes of functions to create
  --stubs=file       generate only function stubs in file
  --xml              generate xml documentation to be added to phpdoc-svn
  --skel=dir         path to the skeleton directory
  --full-xml         generate xml documentation for a self-contained extension
                     (not yet implemented)
  --no-help          don't try to be nice and create comments in the code
                     and helper functions to test if the module compiled

此时不会创建任何目录,当然也不会生成相应的扩展构架。因为它至少需要一个参数,即–extname.

下面我们随便做个测试吧,看看都生成了哪些内容?

netstutekiMacBook-Pro:ext netstu$ ./ext_skel --extname=extdemo
Creating directory extdemo
Creating basic files: config.m4 config.w32 .gitignore extdemo.c php_extdemo.h CREDITS EXPERIMENTAL tests/001.phpt extdemo.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/extdemo/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-extdemo
5.  $ make
6.  $ ./php -f ext/extdemo/extdemo.php
7.  $ vi ext/extdemo/extdemo.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/extdemo/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.

上面提示的信息表示,创建了以扩展名为目录名的一个目录,即 extdemo目录。同时生成了以下几个文件

config.m4 config.w32 .gitignore extdemo.c php_extdemo.h CREDITS EXPERIMENTAL tests/001.phpt extdemo.php

1 .gitignore : git版本管理要忽略的内容,考虑到开发者使用 git,编译扩展后会生成一些临时文件,不需要加入版本控制中。
2. tests/001.phpt, extdemo.php 测试扩展使用的。
3. CREDITS, EXPERIMENTAL文件和扩展的开发没一点关系.

4. 扩展的 config.w32 文件的用法与 config.m4 文件类似,但有两点决定性的不同:首先,它是用于 Windows 构建的,其次,它是使用 JavaScript 编写的。此章节不会包括 JavaScript 语法。目前,代替 Win32 试验台的这部分是不完整的,仅为例子提供的范例 config.m4 的仅试验性质的移植。 (http://www.php.net/manual/zh/internals2.buildsys.configwin.php),说白了,这就是个废品。

5.关于 config.m4,参见: http://baike.baidu.com/subview/84198/12980607.htm
因此,上面的几个文件最重要的是 config.m4,extdemo.c,php_extdemo.h ,只需要修改这几个文件,即可完成一个简单的扩展。

下一节,我们对这几个文件的内容详细做一解释。看看大概的架子到底包括了哪些东西

第 1 页,共 29 页12345...1020...最旧 »