c语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素 首地址的指针。 这样的话,当一个函数调用一维数组的时候,参数的行参可以定义为(char *a)或者 (int *a)或者(int a[]).
性质一. 节点是红色或者黑色的 性质二. 根是黑色的 性质三. 所有的叶子是黑色的(NULL) 性质四. 如果一个节点是红色的,则它的两个儿子都是黑色的。 性质五, 从任一节点到其叶子的所有简单路径都包含相同数目的黑色节点。
http://dev.mysql.com/downloads/connector/c/6.0.html;
其实,我早就把mysql-client安装好了,只是我也不知道怎么安装的当时,看来, 很有必要记录一下当时的安装的情况。
#include<stdio.h>
#include<my_global.h>
#include<mysql.h>
int main(int argc, char **argv){
printf("Mysql client version: %s\n",mysql_get_client_info());
return 0;
}
然后键入命令:
gcc -c `mysql_config --cflags` version.c
然后就生成了可执行文件 version.
或者:
gcc -o version version.o `mysql_config --libs`
相关的练习放在了github中.
这个static其实一点都不安静,这不,你得注意以下几点:
作用域只限于从定义处开始,到文件结尾处,即使你使用extern去申请也不管用的。
在函数体里定义,就只能在这个函数体里面使用,同一文件的其他的函数使用也是 不行的,由于被static修饰??的存放在内存的静态区,就是这个函数运行结束, 变量也不会被撤销。
#include<stdio.h>
static int j;
void fun1(void)
{
static int i = 0;
i ++;
printf("\n");
printf("static's i= %d\t",i);
}
void fun2(void){
j = 0;
j ++;
printf("\n");
printf("non-static j=%d\t",j);
}
int main(){
int k;
for(k = 0; k < 10; k++){
fun1();
fun2();
}
return 0;
}
下面是该段程序的运行结果:
static's i= 1 non-static j=1 static's i= 2
non-static j=1 static's i= 3 non-static j=1
static's i= 4 non-static j=1 static's i= 5
non-static j=1 static's i= 6 non-static j=1
static's i= 7 non-static j=1 static's i= 8
non-static j=1 static's i= 9 non-static j=1
static's i= 10 non-static j=1
从这里我们可以看出来,fun1()内的静态变量没有被释放,还是维持着 上次运行的结果。
这里的修饰,是应该它本来的面目,也就是指该函数只对该文件有效,这样, 不同的人在一个大型项目中不必担心命名冲突。linux kernel中充斥着大量的 static.
作用两个: 1) 对函数返回的限定 2) 对函数参数的限定
如果p1和p2的指针类型相同,我们可以在p1和p2之间相互赋值,如果P1和P2 指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的 指针类型转换为左边指针的类型。 例如:
float *p1;
int *p2;
p1 = p2;
最后一句是错误的,必须按照
p1 =(float *)p2;
来赋值。 但是不能将void类型的指针赋值给有类型的指针。
该标准规定不能对void类型的指针进行算法运算,因为不知道该指针的类型(存储空间)。 但是,GNU委员会不这么认为,它规定void * 的类型与char * 的类型一致。所以, 你想写出移植行很高的代码,需要进行如下的操作:
void *pvoid;
(char *)pvoid++;//ANSI: right
(char *)pvoid += 1; //ANSI: errors
很久之前接触过这个东西,这是很久的事情了。现在又是重新捡起来。
简单说一下,所谓的并查集,顾名思义,就是一个合并、查找的过程。 查找的过程相对简单点,合并的过程需要防止形成单链,理解起来可能有 点麻烦。
其实,很多时候都是自己的数据结构没有学好,连数据的存储形式都搞不明 白。这里我们用数组来模拟一下。
pre[i]
比如pre[3] = 15,就是3的前导点是15,当一个pre[i] == i的时候,就说明 它的前导点就是它自己了,这也是我们的一个过程。
int find(int x){
int r = x;
/*直到找到自己的前导点为自己*/
while(r != pre[r])
r = pre[r];
return r;
}
比如说,在一个集合内含有{1,2,3,4},”1” 为根节点,那么使用 __find(4)__都可以找到1,上面的代码的作用就是这样的.其实,从上面 介绍中,我们也可以看出,这是一棵树。在下面合并的过程中,如果只是 单单把根节点合并在一起,只有两个集合还可以,有很多个集合就会费很大 的力气。为此,我们在查找的过程中,可以适当做一些优化,这一步被成为 路径压缩。比如:
1 1---- / \ 优化成: /|\ | 2 5 ——————--> 2 4 5 6 / \ 4 6
利用上面的find
函数,找到了x的根节点,那么,我们可以认为在这个查
找的过程中,所经历的节点的根节点都是x的根节点,那么:
int find(int x){
int r = x;
while(r != pre[r])
r = pre[r];
int i, j = x;
while(r != pre[j]){
i = pre[j];
/*根节点赋值给经过路径上的节点*/
pre[j] = r;
j = i;
}
}
这一步就是将两个树形节点合并起来。
void union(int x, int y){
int tx = find(x);
int ty = find(y);
/*将y的前导点设置为x*/
if(tx != ty)
pre[ty] = tx;
}
来自hdu上的题目。连通点: 给定n个节点,m条边,接下来是m条边的两个端点,问只需要连接几条边,就可以将 所有的边连接起来且没有回路.
这道题目就是简简单单的问连通集的个数,连成一条线的话就再减去1.
#include<stdio.h>
int pre[1050];
int flags[1050];
int find(int x){
/* you must don't forget */
int r = x;
while(r != pre[r]){
r = pre[r];
}
int j = x, i;
while(pre[j] != r){
i = pre[j];
pre[j] = r;
j = i;
}
return r;
}
void mix(int a,int b){
int root_a = find(a);
int root_b = find(b);
if(root_a != root_b)
pre[a] = b;
}
int main()
{
int n,m,a,b;
int i,j;
freopen("find.in","r",stdin);
scanf("%d%d",&n,&m);
for(i = 1; i <= n; i++){
pre[i] = i;
/*将自己本身设为自己的前导点*/
flags[i] = 0;
}
for(j = 1; j <= m; j++){
scanf("%d%d",&a,&b);
mix(a,b);
}
for(i = 1; i <= n; i++){
flags[find(i)] = 1;
}
int ans = 0;
for(i = 1; i <= n; i++)
{
if(flags[i] == 1)
ans++;
}
printf("total ans is %d\n",ans - 1);
}
为了减少以后不必要的麻烦,这里暂时把时间日期打乱了,自己心里有数就行。[2016-09-27]
我是9月18号离的职,出来以后就回到学校,什么人也不想见,幸亏我的女朋友,陪我度过这一段糟糕的时间。
我居然二战了,内心是无比的复杂,今天就是这样,想起去年那些浪费的时间,自己就不能释怀了,自己做题也是 效率低的要命。
最要命的不是效率,而是我要报哪个学校?我想找一个与linux打交道的学校,为了两个人在一起,也可以去同一个 城市。
人啊,最怕的是欲望太多,或者说是幻想太强,在有一个领域里做不强,在其他领域里也是格外的痛苦。
我现在就是窝在学校南面的一个简易板房里发出的这篇博客,在以后的某段时间里,无论是开心还是失落, 时刻明白自己要的是什么,怎样去争取,而不能自暴自弃或者痴心妄想。
二战失败也是可以接受的,这只是你的生命里一条与他人不同的轨迹,在你忙着活命的时候,别人也是如此。
还有不到三个月的时间,努力忘掉自我,消失就对了。
生命不息。