10种简单的数字滤波算法(C语言源程序)

1、限幅滤波法(又称程序判断滤波法)

 A、方法:

 根据经验判断,确定两次采样允许的最大偏差值(设为A)

 每次检测到新值时判断:

 如果本次值与上次值之差<=A,则本次值有效

 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值

 B、优点:

 能有效克服因偶然因素引起的脉冲干扰

 C、缺点

 无法抑制那种周期性的干扰

 平滑度差

#define A 10
char value;
char filter()
{
  char  new_value;
  new_value = get_ad();
  if ( ( new_value – value > A ) || ( value – new_value > A )
     return value;
  return new_value;
}

2、中位值滤波法

 A、方法:

 连续采样N次(N取奇数)

 把N次采样值按大小排列

 取中间值为本次有效值

 B、优点:

 能有效克服因偶然因素引起的波动干扰

 对温度、液位的变化缓慢的被测参数有良好的滤波效果

 C、缺点:

 对流量、速度等快速变化的参数不宜

#define N  11
char filter()
{
  char value_buf[N];
  char count,i,j,temp;
  for ( count=0;count<N;count++)
  {
     value_buf[count] = get_ad();
     delay();
  }
  for (j=0;j<N-1;j++)
  {
     for (i=0;i<N-j;i++)
     {
        if ( value_buf[i]>value_buf[i+1] )
        {
           temp = value_buf[i];
           value_buf[i] = value_buf[i+1]; 
            value_buf[i+1] = temp;
        }
     }
  }
  return value_buf[(N-1)/2];
    

3、算术平均滤波法

 A、方法:

 连续取N个采样值进行算术平均运算

 N值较大时:信号平滑度较高,但灵敏度较低

 N值较小时:信号平滑度较低,但灵敏度较高

 N值的选取:一般流量,N=12;压力:N=4

 B、优点:

 适用于对一般具有随机干扰的信号进行滤波

 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动

 C、缺点:

 对于测量速度较慢或要求数据计算速度较快的实时控制不适用

 比较浪费RAM
#define N 12
char filter()
{
  int  sum = 0;
  for ( count=0;count<N;count++)
  {
     sum + = get_ad();
     delay();
  }
  return (char)(sum/N);
}

4、递推平均滤波法(又称滑动平均滤波法)

 A、方法:

 把连续取N个采样值看成一个队列

 队列的长度固定为N

 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)

 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果

 N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4

 B、优点:

 对周期性干扰有良好的抑制作用,平滑度高

 适用于高频振荡的系统

 C、缺点:

 灵敏度低

 对偶然出现的脉冲性干扰的抑制作用较差

 不易消除由于脉冲干扰所引起的采样值偏差

 不适用于脉冲干扰比较严重的场合

 比较浪费RAM


#define N 12 
char value_buf[N];
char i=0;
char filter()
{
  char count;
  int  sum=0;
  value_buf[i++] = get_ad();
  if ( i == N )   i = 0;
  for ( count=0;count<N,count++)
     sum = value_buf[count];
  return (char)(sum/N);
}

5、中位值平均滤波法(又称防脉冲干扰平均滤波法)

 A、方法:

 相当于“中位值滤波法”+“算术平均滤波法”

 连续采样N个数据,去掉一个最大值和一个最小值

 然后计算N-2个数据的算术平均值

 N值的选取:3~14

 B、优点:

 融合了两种滤波法的优点

 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差

 C、缺点:

 测量速度较慢,和算术平均滤波法一样

 比较浪费RAM


#define N 12
char filter()
{
  char count,i,j;
  char value_buf[N];
  int  sum=0;
  for  (count=0;count<N;count++)
  {
     value_buf[count] = get_ad();
     delay();
  }
  for (j=0;j<N-1;j++)
  {
     for (i=0;i<N-j;i++)
     {
        if ( value_buf[i]>value_buf[i+1] )
        {
           temp = value_buf[i];
           value_buf[i] = value_buf[i+1]; 
            value_buf[i+1] = temp;
        }
     }
  }
  for(count=1;count<N-1;count++)
     sum += value[count];
  return (char)(sum/(N-2));
}

6、限幅平均滤波法

 A、方法:

 相当于“限幅滤波法”+“递推平均滤波法”

 每次采样到的新数据先进行限幅处理,

 再送入队列进行递推平均滤波处理

 B、优点:

 融合了两种滤波法的优点

 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差

 C、缺点:

 比较浪费RAM

  
略 参考子程序1、3

7、一阶滞后滤波法

 A、方法:

 取a=0~1

 本次滤波结果=(1-a)*本次采样值+a*上次滤波结果

 B、优点:

 对周期性干扰具有良好的抑制作用

 适用于波动频率较高的场合

 C、缺点:

 相位滞后,灵敏度低

 滞后程度取决于a值大小

 不能消除滤波频率高于采样频率的1/2的干扰信号


#define a 50
char value;
char filter()
{
  char  new_value;
  new_value = get_ad();
  return (100-a)*value + a*new_value; 
}

8、加权递推平均滤波法

 A、方法:

 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权

 通常是,越接近现时刻的数据,权取得越大。

 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低

 B、优点:

 适用于有较大纯滞后时间常数的对象

 和采样周期较短的系统

 C、缺点:

 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号

 不能迅速反应系统当前所受干扰的严重程度,滤波效果差


#define N 12
char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};
char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;
char filter()
{
  char count;
  char value_buf[N];
  int  sum=0;
  for (count=0,count<N;count++)
  {
     value_buf[count] = get_ad();
     delay();
  }
  for (count=0,count<N;count++)
     sum += value_buf[count]*coe[count];
  return (char)(sum/sum_coe);
}

9、消抖滤波法

 A、方法:

 设置一个滤波计数器

 将每次采样值与当前有效值比较:

 如果采样值=当前有效值,则计数器清零

 如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)

 如果计数器溢出,则将本次值替换当前有效值,并清计数器

 B、优点:

 对于变化缓慢的被测参数有较好的滤波效果,

 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动

 C、缺点:

 对于快速变化的参数不宜

 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统

#define N 12
char filter()
{
  char count=0;
  char new_value;
  new_value = get_ad();
  while (value !=new_value);
  {
     count++;
     if (count>=N)   return new_value;
      delay();
     new_value = get_ad();
  }
  return value;    
}

10、限幅消抖滤波法

 A、方法:

 相当于“限幅滤波法”+“消抖滤波法”

 先限幅,后消抖

 B、优点:

 继承了“限幅”和“消抖”的优点

 改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统

 C、缺点:

 
略 参考子程序1、9

字符设备 register_chrdev_region()、alloc_chrdev_re

内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里。该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下:

  static struct char_device_struct {
      struct char_device_struct *next;    // 指向散列冲突链表中的下一个元素的指针
      unsigned int major;                 // 主设备号
      unsigned int baseminor;             // 起始次设备号
      int minorct;                        // 设备编号的范围大小
      char name[64];                      // 处理该设备编号范围内的设备驱动的名称
      struct file_operations *fops;       // 没有使用
      struct cdev *cdev;                  // 指向字符设备驱动程序描述符的指针
  } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];

注意,内核并不是为每一个字符设备编号定义一个 char_device_struct 结构,而是为一组对应同一个字符设备驱动的设备编号范围定义一个 char_device_struct 结构。chrdevs 散列表的大小是 255,散列算法是把每组字符设备编号范围的主设备号以 255 取模插入相应的散列桶中。同一个散列桶中的字符设备编号范围是按起始次设备号递增排序的。

注册
内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()。这三个函数都会调用一个共用的 __register_chrdev_region() 函数来注册一组设备编号范围(即一个 char_device_struct 结构)。

register_chrdev_region(dev_t first,unsigned int count,char *name)
First :要分配的设备编号范围的初始值(次设备号常设为0);
Count:连续编号范围.
Name:编号相关联的设备名称. (/proc/devices);
动态分配:
Int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);
Firstminor : 通常为0;
*dev:存放返回的设备号;
释放:
Void unregist_chrdev_region(dev_t first,unsigned int count);
调用Documentation/devices.txt中能够找到已分配的设备号.

所以下面先来看一下 __register_chrdev_region() 函数的实现代码。

static struct char_device_struct * __register_chrdev_region(unsigned int major, unsigned int baseminor, int minorct, const char *name)
{
  struct char_device_struct *cd, **cp;
  int ret = 0;
  int i;

  cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
  if (cd == NULL)
      return ERR_PTR(-ENOMEM);

  mutex_lock(&chrdevs_lock);

  if (major == 0) {
       for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i–)
          if (chrdevs[i] == NULL)
              break;

      if (i == 0) {
          ret = -EBUSY;
          goto out;
      }
      major = i;
      ret = major;
  }

  cd->major = major;
  cd->baseminor = baseminor;
  cd->minorct = minorct;
  strncpy(cd->name,name, 64);

  i = major_to_index(major);

  for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
      if ((*cp)->major > major ||
           ((*cp)->major == major && ( ((*cp)->baseminor >= baseminor) || ((*cp)->baseminor + (*cp)->minorct > baseminor)) ))
          break;

 
  if (*cp && (*cp)->major == major) {
      int old_min = (*cp)->baseminor;
      int old_max = (*cp)->baseminor + (*cp)->minorct – 1;
      int new_min = baseminor;
      int new_max = baseminor + minorct – 1;

     
      if (new_max >= old_min && new_max <= old_max) {
          ret = -EBUSY;
          goto out;
      }

     
      if (new_min <= old_max && new_min >= old_min) {
          ret = -EBUSY;
          goto out;
      }
  }

  cd->next = *cp;
  *cp = cd;
  mutex_unlock(&chrdevs_lock);
  return cd;
out:
  mutex_unlock(&chrdevs_lock);
  kfree(cd);
  return ERR_PTR(ret);
}
函数 __register_chrdev_region() 主要执行以下步骤:
1. 分配一个新的 char_device_struct 结构,并用 0 填充。
2. 如果申请的设备编号范围的主设备号为 0,那么表示设备驱动程序请求动态分配一个主设备号。动态分配主设备号的原则是从散列表的最后一个桶向前寻找,那个桶是空的,主设备号就是相应散列桶的序号。所以动态分配的主设备号总是小于 256,如果每个桶都有字符设备编号了,那动态分配就会失败。
3. 根据参数设置 char_device_struct 结构中的初始设备号,范围大小及设备驱动名称。
4. 计算出主设备号所对应的散列桶,为新的 char_device_struct 结构寻找正确的位置。同时,如果设备编号范围有重复的话,则出错返回。
5. 将新的 char_device_struct 结构插入散列表中,并返回 char_device_struct 结构的地址。

分析完 __register_chrdev_region() 后,我们来一个个看那三个注册函数。首先是 register_chrdev_region()。

register_chrdev_region() 函数用于分配指定的设备编号范围。如果申请的设备编号范围跨越了主设备号,它会把分配范围内的编号按主设备号分割成较小的子范围,并在每个子范围上调用 __register_chrdev_region() 。如果其中有一次分配失败的话,那会把之前成功分配的都全部退回。

alloc_chrdev_region() 函数用于动态申请设备编号范围,这个函数好像并没有检查范围过大的情况,不过动态分配总是找个空的散列桶,所以问题也不大。通过指针参数返回实际获得的起始设备编号。

最后一个 register_chrdev() 是一个老式分配设备编号范围的函数。它分配一个单独主设备号和 0 ~ 255 的次设备号范围。如果申请的主设备号为 0 则动态分配一个。该函数还需传入一个 file_operations 结构的指针,函数内部自动分配了一个新的 cdev 结构。关于这些,在后续讲字符设备驱动的注册时会说明。

注销
和注册分配字符设备编号范围类似,内核提供了两个注销字符设备编号范围的函数,分别是 unregister_chrdev_region() 和 unregister_chrdev() 。它们都调用了 __unregister_chrdev_region() 函数。

struct-timeval 用法

gettimeofday() — 获取当前时间(保存在结构体timeval中)

例子:

#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int main(int argc, char * argv[]){
   struct timeval tv;                //(1)
   while(1){
       gettimeofday(&tv, NULL);      //(2)
       printf(“time %u:%u\n”, tv.tv_sec, tv.tv_usec);
       sleep(2);
   }
   return 0;

}

(1) struct–timeval

struct timeval {
   time_t      tv_sec;    
   suseconds_t tv_usec;   
};
millisecond        毫秒
microsecond        微秒
timeval表示一个时间点,比如:
timeval.tv_sec = 1   (s)
timevat.tv_usec = 500 000 (
μs)
1:500 = 1s500000
μs = 1.5s
(2) gettimeofday()
int gettimeofday(struct timeval *tv, struct timezone *tz); 

 
gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中。

timezone 结构定义为:
struct timezone{
int tz_minuteswest;
int tz_dsttime;
};

C++中的static用法

简介

C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。

面向过程设计中的static

1、静态全局变量

在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:

//Example 1

#include <iostream.h>

void fn();

static int n; //定义静态全局变量

void main()

{ n=20;

cout<<n<<endl;

fn();

}

void fn()

{

n++;

cout<<n<<endl;

}

静态全局变量有以下特点:

该变量在全局数据区分配内存;

未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);

静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;

静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:

代码区 //low address

全局数据区

堆区

栈区 //high address

一般程序把新产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静 态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将

static int n; //定义静态全局变量

改为

int n; //定义全局变量

程序照样正常运行。

的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:

静态全局变量不能被其它文件所用;

其它文件中可以定义相同名字的变量,不会发生冲突;

您可以将上述示例代码改为如下:

//Example 2//File1

#include <iostream.h>

void fn();

static int n; //定义静态全局变量

void main()

{ n=20;

cout<<n<<endl;

fn();

}

//File2

#include <iostream.h>

extern int n;

void fn()

{ n++;

cout<<n<<endl;

}

编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。 试着将

static int n; //定义静态全局变量

改为

int n; //定义全局变量

再次编译运行程序,细心体会全局变量和静态全局变量的区别。

注意:全局变量和全局静态变量的区别

1)全局变量是不显式用static修饰的全局变量,但全局变量默认是静态的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。

2)全局静态变量是显式用static修饰的全局变量,作用域是所在的文件,其他的文件即使用extern声明也不能使用。

2、静态局部变量

在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。

我们先举一个静态局部变量的例子,如下:

//Example 3

#include <iostream.h>

void fn();

void main()

{ fn();

fn();

fn();

}

void fn()

{ static int n=10;

cout<<n<<endl;

n++;

}

通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。

但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。

静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

静态局部变量有以下特点:

该变量在全局数据区分配内存;

静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;

静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;

它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

3、静态函数

在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。

静态函数的例子:

//Example 4

#include <iostream.h>

static void fn();//声明静态函数

void main()

{

fn();

}

void fn()//定义静态函数

{ int n=10;

cout<<n<<endl;

}

定义静态函数的好处:

静态函数不能被其它文件所用;

其它文件中可以定义相同名字的函数,不会发生冲突;

面向对象的static关键字

(类中的static关键字)

1、静态数据成员

在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。

//Example 5

#include <iostream.h>

class Myclass

{

public:

Myclass(int a,int b,int c);

void GetSum();

private:

int a,b,c;

static int Sum;//声明静态数据成员

};

int Myclass::Sum=0;//定义并初始化静态数据成员

Myclass::Myclass(int a,int b,int c)

{ this->a=a;

this->b=b;

this->c=c;

Sum+=a+b+c;}

void Myclass::GetSum()

{ cout<<“Sum=”<<Sum<<endl;

}

void main()

{ Myclass M(1,2,3);

M.GetSum();

Myclass N(4,5,6);

N.GetSum();

M.GetSum();}

可以看出,静态数据成员有以下特点:

对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷 贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共 用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;

静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在Example 5中,语句int Myclass::Sum=0;是定义静态数据成员;

静态数据成员和普通数据成员一样遵从public,protected,private访问规则;

因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;

静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:

<数据类型><类名>::<静态数据成员名>=<值>

类的静态数据成员有两种访问形式:

<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;

静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这 有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,所以节省存储空间。第二,一旦利息需要改变时,只要改变一次, 则所有存款类对象的利息全改变过来了;

同全局变量相比,使用静态数据成员有两个优势:

静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;

可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;

2、静态成员函数

与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部 实现,属于类定义的一部分。 普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。 下面举个静态成员函数的例子。

//Example 6

#include <iostream.h>

class Myclass

{public:

Myclass(int a,int b,int c);

static void GetSum();/声明静态成员函数

private:

int a,b,c;

static int Sum;//声明静态数据成员

};

int Myclass::Sum=0;//定义并初始化静态数据成员

Myclass::Myclass(int a,int b,int c)

{ this->a=a;

this->b=b;

this->c=c;

Sum+=a+b+c; //非静态成员函数可以访问静态数据成员

}

void Myclass::GetSum() //静态成员函数的实现

{// cout<<a<<endl; //错误代码,a是非静态数据成员

cout<<“Sum=”<<Sum<<endl;

}

void main()

{ Myclass M(1,2,3);

M.GetSum();

Myclass N(4,5,6);

N.GetSum();

Myclass::GetSum();

}

关于静态成员函数,可以总结为以下几点:

出现在类体外的函数定义不能指定关键字static;

静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;

非静态成员函数可以任意地访问静态成员函数和静态数据成员;

静态成员函数不能访问非静态成员函数和非静态数据成员;

由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;

调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:

<类名>::<静态成员函数名>(<参数表>)

调用类的静态成员函数。

作用

static静态变量声明符。 在声明它的程序块,子程序块或函数内部有效,值保持,在整个程序期间分配存储器空间,编译器默认值0。

是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

为什么要引入static

函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

什么时候用static

需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

static的内部机制

静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。

这样,它的空间分配有三个可能的地方,一是作为类的外部接口的头文件,那里有类声明;二是类定义的内部实现,那里有类的成员函数定义;三是应用程序的main()函数前的全局数据声明和定义处。

静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。类声明只声明一个类的“尺寸和规格”,并不进行实际的内存分配,所以在类声明中写成定义是错误的。它也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。

static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态

数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。

static的优势

可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

应用格式

引用静态数据成员时,采用如下格式:

<类名>::<静态成员名>

如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。

注意事项

(1)类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。

(2)不能将静态成员函数定义为虚函数。

(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,就多少有些特殊,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。

(4)由于静态成员函数没有this指针,所以就差不多等同于nonmember函数,结果就产生了一个意想不到的好处:成为一个callback函数,使得我们得以将C++和C-based X Window系统结合,同时也成功的应用于线程函数身上。

(5)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问时间,节省了子类的内存空间。

(6)静态数据成员在<定义或说明>时前面加关键字static。

(7)静态数据成员是静态存储的,所以必须对它进行初始化。

(8)静态成员初始化与一般数据成员初始化不同:

初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;

初始化时不加该成员的访问权限控制符private,public等;

初始化时使用作用域运算符来标明它所属类;

所以我们得出静态数据成员初始化的格式:

<数据类型><类名>::<静态数据成员名>=<值>

(9)为了防止父类的影响,可以在子类定义一个与父类相同的静态变量,以屏蔽父类的影响。这里有一点需要注意:我们说静态成员为父类和子类共享,但我们有重复定义了静态成员,这会不会引起错误呢?不会,我们的编译器采用了一种绝妙的手法:name-mangling 用以生成唯一的标志。在各通信公司的笔试面试中经常出现的考题就是static的作用及功能。

vc++编译error LNK2001| unresolved external symbol _WinMain@16|symbol __beginthreadex

在编译VC++程序时,出现Linking… /subsystem:windows
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/TestWin.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

1.原因

解决这个错误首先在新建工程时要分清Win32 Application和Win32 Console Application,因为Win32 Application的入口函数为WinMain,Win32 Console Application的入口函数是main。就是说,如果你编写传统的C程序,必须建立Win32 Console程序,但VC里面默认的是Win32 Application,于是上面提及的链接错误就就经常出现了。

2.解决办法

将[project]-[settings]-[link]的project options里的 /subsystem:windows
改成 /subsystem:console

我发现与前几天出现的libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main(解决办法见另一篇文章http://renrenstudy.com/php/vc-6-0-compile-error/)有几分相似,好多错误之前都会出现error LNK2001,于是我在网上浏览类似错误原因,还有解决办法,这里整理一下,方便亲们以后查询:

1.libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

解决方法:
见另一篇文章http://renrenstudy.com/php/vc-6-0-compile-error/

2.LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16

解决方法:见上文
3.msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16

解决方法:MFC项目的程序入口函数是WinMain, 如果编译项目的Unicode版本, 程序入口必须改为wWinMainCRTStartup, 所以需要重新设置程序入口:
[Project] –> [Settings] –> 选择”C/C++”属性页,
在Category中选择Output,
再在Entry-point symbol中填入wWinMainCRTStartup, 即可

4.nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

解决方法:

线程运行时库设置错误,这是因为MFC要使用多线程时库, 需要更改设置:
[Project] –> [Settings] –> 选择”C/C++”属性页,
在Category中选择Code Generation,
再在Use run-time library中选择Debug Multithreaded或者multithreaded
其中,
Single-Threaded                  单线程静态链接库(release版本)
Multithreaded                    多线程静态链接库(release版本)
multithreaded DLL                多线程动态链接库(release版本)
Debug Single-Threaded            单线程静态链接库(debug版本)
Debug Multithreaded              多线程静态链接库(debug版本)
Debug Multithreaded DLL          多线程动态链接库(debug版本)
单线程: 不需要多线程调用时, 多用在DOS环境下
多线程: 可以并发运行
静态库: 直接将库与程序Link, 可以脱离MFC库运行
动态库: 需要相应的DLL动态库, 程序才能运行
release版本: 正式发布时使用
debug版本: 调试阶段使用

Cannot send session cache limiter – headers already sent 错误解决办法

在windows下编程,当使用session_start()方法的时候,有时会报
session_start() [function.session-start]: Cannot send session cache limiter – headers already sent (output started at /var/www/inpublisher/php1.php:1)这样的错误,说是已经有输出,用编辑器打,前面明明什么都没有,原来在使用AJAX的 时候,也出现过这种情况,后来,把这个PHP文件放到linux中打开,会发现,在文件的最前面,会出现“锘 ”这样的一个字符(引号内),把它去掉以后,再运行,OK,运行正常。后来在网上搜索一些文件,给的解释是:UTF8文件的BOM(Byte Order Mark)标志,在保存的时候会自动存入!
不管它是干嘛的,现在的目的就是把它去掉,我总结的方法有下面三种:
1、       在Linux下打开,去掉后再保存
2、       用写字板打开,把光标放到最前后回车,然后再敲删除,重新回到第一行,这样最前面的那个字符就会去掉
3、       使用UltraEdit编辑器(很好用的一个编辑器,网上多的是,自己下去),打开高级—-配置—-Unicode/utf-8 检测,把自动检测UTF-8文件,自动检测没有BOM的Unicode文件等前面的勾全去掉,然后你再打开那个文件,就会发觉“锘 ”这个字符出现了,删除就OK了
4、设置您的编辑器:在编辑utf-8文件时不添加BOM,以Edit plus为例:您需要将工具->参数->文件->UTF_8签名一项中,”总是添加签名”选项改为”总是移除签名”.这样重新编辑保存相应文件后就能解决这个问题.
5、我使用的是notepad++,如下图所示,将文件“转为UTF-8无BOM编码格式”就可以了,转换后可以看到文件已经以UTF-8无BOM编码了。

用notepad++清除bom

 

网站被降权了?

今天去百度site:renrenstudy.com,结果发现renrenstudy.com已经不在首位了。

按照网上的说法,应该是站点被降权了。

但仔细想想,最近也没进行什么”非法”的操作,还是先耐心等等吧。

9月26日记录:

中午去百度site了一下,发现首页已经回到了首位。

目前怀疑两个原因:
第一,前两天与几个博客互换了友情链接。据说做全站链接一般都会遭到降权。
第二,原来在renrenstudy.com下建了个bbs的子目录,放了个DiscuzX2的论坛,虽然没推广,但也引来了很多的垃圾链接。

9月26日记录:

还有一个不容易想到的降权原因:共享IP的其他虚拟主机。

10月3日记录:

今天想要修改网站标题,突然想到上次的降权很有可能只是因为将首页的标题进行了修改,造成了首页的排名下降。

Discuz X2如何添加nofollow标签 – 插件推荐:外链杀手-防垃圾外链

我们都知道,反向链接即外链是搜索引擎给网站排名的一个重要因素。为了添加反向链接,SEO作弊者会在论坛和博客等大量发布带无关链接的内容。这些垃圾链接的存在给搜索引擎对网页质量的评估造成一定程度的麻烦,可以说nofollow是一个非常好的“垃圾链接防火墙”。正是百度、谷歌、Yahoo、MSN 为了应对垃圾链接(Spam)引入的一个属性,此属性目前应该被广泛采用。

external nofollow是比nofollow更专业的写法,即明确指出链接为外部链接,爬虫可以略过。

1.本插件支持 “域名白名单”,可以不对 白名单 里的域名进行处理。
2.对站外链进行搜索引擎封杀 ,保证本站链接投票权重,即明确指出链接为外部链接,爬虫可以略过。
3.对蜘蛛进行判断,即使别人查看你网页源代码也看不出你对外链做了手脚。
4.可自行选择使用 external nofollow 还是 nofollow 默认 external nofollow 。
5.可以选择使用链接杀手的版块。

插件下载地址:http://www.discuz.net/forum.php?mod=viewthread&tid=2152122

中国的普通互联网用户相对低端,对他们来说,互联网越简单越好

目前拥有上亿用户的4399定位为国内最大中文游戏发行平台,其中网页游戏注册用户1200多万,每天新增用户近20万,每日流量1600万,平均同时在线80万,月收入达到千万,盛大、巨人等大公司都开始与其合作。

一个有趣的问题是,无论是hao123还是4399,其页面都极不美观,这让互联网精英们无法理解,为什么这样的网站能够获得这么大的流量,其成功的原因是什么?

“中国的普通互联网用户相对低端,对他们来说,互联网越简单越好。我曾做过实验,我让五六岁的小孩同时玩4399和其他小游戏网站的游戏,一个星期之后,他会更喜欢使用4399。”蔡文胜说。这多少和当年李彦宏对hao123的评价类似:“hao123简单到让人无法超越。”

nofollow外链对排名有没有作用 | nofollow友情链接

首先我们看一下讯鹰SEO的一篇《你的网站外链是否受到nofollow标签的影响》中的分析。

自seo发展至今,这个行业可谓是鱼目混杂,五花八门。在遵循seo宗旨的前提下,各个站长可以说是百家争鸣,各执一词。不同于战国时期诸子百家学派的是,当时诸子学说是要根据社会发展和实践验证的,而seo中遵循着万变不离其中的一点,那就是搜索引擎算法和搜索引擎管理员推出的相应规则。所以,seo有着行乱而神不乱的内在因素。

seo发展中,Google率先推出PR值,代表一个网站的权重。而提高网站权重最有效的方法就是获得网站外链。随之而来的就是站长们为提高自身网站权重,纷纷增加自己网站外链,各个网站充斥着相关或不相关的链接。

垃圾链接盛行,或多或少的影响着搜索引擎对网站的判断。对此Google再次新创了一个标签——nofollow。它是一个HTML标签的属性值,即告诉搜索引擎”不要追踪此网页上的链接”或”不要追踪此特定链接。如A站有一个链接指向讯鹰博客,但A站给这个链接加上了nofollow标签。此时,搜索引擎并不将A站网页计算入讯鹰博客的反向链接内,搜索引擎看到这个标签就可能减少或完全取消链接的投票权重。当我们在友情链接的时候,若碰上这种情况将大大减少友情链接的作用。所以,做友情链接的时候,我们不得不注意一下,对方是否为你的链接加上了nofollow标签。

在我们警惕nofollow标签的同时,也应该知晓其不可忽视的作用。nofollow标签的问世,就是为了防止垃圾链接的盛行,故被称为“垃圾链接防火墙”。仅此,nofollow属性标签就应该得到广泛应用,遏制互联网上垃圾信息的蔓延。

说下我的见解。

我们可以主要到上文的这么一句话:在我们警惕nofollow标签的同时,也应该知晓其不可忽视的作用。nofollow标签的问世,就是为了防止垃圾链接的盛行,故被称为“垃圾链接防火墙”。

nofollow标签被提出的初衷,就是为了防止垃圾链接。

也就是,这个标签是搜索引擎帮助解决站长来指明哪些是垃圾链接的,让站长合理安排权重的传递走向。

所以,你还会自欺欺人的认为nofollow的友情链接会有作用吗?不要骗自己了。

既然要做友情链接,为什么要加nofollow标签,不想让自己站点的权重传递给友情链接?

那还有什么交换友链的意义。“友情”两字也变得更加讽刺了。

百度排名法则

百度排名法则:

这个问题,相信很多seoer会感情绪,那么本人今天在就这讲一下本人对百度排名法则的看法,首先是上面的问题,PR值对于百度来说其实没有直接联系,PR值得多少和排名没有关联,并且谷歌也说过,排名和PR值没有关联,那么PR值得意义在哪呢?PR值=网页质量,网页质量是什么?网页质量=用户体验。用户体验又是什么?用户体验=PV值,跳出率,关键词访问率,相关网页锚文本访问次数……而百度一直崇尚的就是用户体验第一。这也就是为什么前一阵子百度点击器运行的原理。这也和夫唯的五条金律非常贴近。

总结下,百度排名法则:

1、外链占百度排名影响因素,要占到30%左右(外链数量,外链质量等)

2、用户体验占百度排名影响因素,要占到25%左右(网页质量,网站正常访问稳定性,PV值,跳出率,死链接数量等)

3、域名,空间因素占百度排名影响因素,要占到10%左右(网站域名时间长短,空间打开速度,空间稳定性等)

4、网站内部结构优化占百度排名影响因素,要占到20%左右(图片alt属性,网站框架-div+css结构,路径静态化,首选域等等)

5、其他因素占百度排名影响因素,要占到5%左右(网站合法性,网站域名备案等不确定因素。)

总之,上面的五点可能没有那么精确话,但是估算的话,上面的五种法则,至少要站百度排名算法的50%以上。因此,从上面的法则入手,不采用作弊的手法,一定会尽可能让你的网站在百度有个良好的表现。

引自郑州SEO

快速增加反链的十种方法

一、只要能留名的地方,就能留下你的地址。无论在网上浏览到什么地方,做到“人过留名”,是走向反链建设的第一步。不过,要注意,很多网站虽然能留网址,但是却是网址转向,也等于是无效的。所以大家在用这个方法前,一定要先看看对方的网站,可以不可以留超链,否则就是瞎忙活了。

二、购买各类论坛高发帖量ID(可放置链接签名的论坛)。这样我们在购买该ID并在其个人签名中添加我们的网址,那么该ID发表过的所有帖子都存在了反链。可以选择一些名气不是特别大,但是在引擎中表现特别出色的论坛来购买,最好不要选择站长性质的论坛,因为站长性质的论坛人家知道你买了签名是做什么的,价格就会涨上去。一般去一些地区性论坛或者娱乐性论坛购买ID,你会用相对较低的价格,买到发帖量足够多的ID的。那么什么算是在引擎中表现出色的论坛呢?举个例子,你在该论坛发帖,1个小时内该贴被引擎收录的则为“特别出色”的论坛,即可选择在该论坛购买ID。购买好ID后,记得将ID内的签名修改成描文字链接,至于文字内容,完全可以选择你站首页的关键词。

三、原创优秀文章投稿。很多专业性站点都带有用户投稿系统,一篇扣人心弦、发人深省的文章往往会得到编辑的青睐,我们可在文末添加一个小小的网址,切莫不可在文内添加网址哦,一来影响读者阅读,二来影响自己的说服力,让人一眼就觉得这只是篇可能是抄来的软文。只要你的文章有力度,我相信善良的编辑们也是乐于保留你的版权信息的,由此,该文在被转载地同时,你将以最小的付出换回最多的反链。个人认为,此种方法获得的反链是相对高质量的,比起论坛的签名或是论坛发帖,要有效地多。

四、交换友情链接。尽量找与你的站点关键词、内容相近的站点作友情链接,这样作友情链接的效果非常好。为了具体说明交换友情连接的目的和方法,下面引用一篇《交换友情链接终极技巧大全》的文章。

一、交换友情链接的目的

1、提升PR。这是交换友情链接最根本的目的。如果知道什么是PR值的,请看最下面的名词解释。

2、提高关键字排名。这也是目的之一,其重要性不必赘述,有关关键字优化的技巧,参看笔者以前的文章《江礼坤:在搜索中如何提高关键字排名》。

3、提高网站权重。这点很重要,只有你的权重高了,搜索引擎才会重视你。

4、提高知名度。这条还是比较有针对性的,对于一些特定的网站和特定的情况,才会达到此效果。比如一个不知名的新站,如果能与新浪、SOHU、YAHOO、网易、腾讯、3G网址大全等大的网站全都做上链接的话,那肯定对其知名度及品牌形象是一个极大的提升。

5、提高流量。这条几乎可以忽略不计,但是之所以写上,是因为很多新人有个误区,以为换友情链接是为了增加流量,所以在这里严重纠正一下,友情链接对于流量的提升帮助非常小,如果友情链接带来的那几个IP能影响到您网站的流量话,那这个网站有没有存在下去的必要就很值得商榷了。其实笔者刚学习建网站时,也是这么认为的。

二、什么是优质的链接

1、Alexa排名。Alexa排名代表的是流量,当然,有人说了,不少网站的排名是通过作弊得来的,看这个没意义。有排名的网站确实不一定有流量,但是没排名的网站一定没流量。至于与排名多高的网站交换适宜,没有明确的标准,笔者认为别比你自己网站的排名低太多就成。

2、PR值。这个代表的是网站的权重,只有与权重高的网站交换链接,才会提升自己的权重。通常来说,只要对方的PR值比自身高就可以换。不过笔者认为至少应该达到4才算是一个优质的链接。

3、知名度。对方网站最好具有一定的知名度,或在行业内具有一定的影响力。

4、关联性。对方网站的主题内容要与我方网站有一定的关联性。

6、网页快照。对方的网页快照时间,最好在天天之内。

7、收录数。第一,搜索引擎的收录数与其网站的实际内容数,不应该相差太大。第二,对方网站在百度与GOOGLE的收录数最好不要相差太大,这个可以参考其同类网站的在不同搜索引擎的收录比例。

8、更新速度。对方网站的内容最好是天天有更新,只有天天更新的网站,搜索引擎才会重视,用户才会喜欢,链接了也才有价值。

三、坚决不换的链接

1、假PR。通常假PR是指利用PR劫持技术去欺骗PR值的一种手段。不过识别也是很容易的,有很多在线的识别工具。

2、导出链接太多。即使对方的PR值是10,但是如果有几百个链接的话,那实际上分到你头上也没多少了。

3、内页链接。坚决不做内页链接,内页链接往往是没有任何意义的。因为专门的友情链接页,不会每天更新,而且通常友情链接页也没有很高的PR值。

4、JS链接。这个坚决不能换,搜索引擎是根本看不到JS里面有什么的。搜索引擎看不到,也就意味着这个链接无效。

5、没有PR值的页面坚决不换。之所以把这条写出来,是因为很多新人呀,以为对方网站只要有PR,那和他的任何页面换了就有效果,其实不是这样的,一定要与对方那个有PR值的页面直接交换才行。各位看官莫笑,确实很多新人有这个误区。

四、获取链接的渠道

1、个人关系。新网站没有PR值、没有排名、没有流量,所以肯定没人愿意和你换了。所以这个时候只能靠个人关系了,有时候为了生存,只能先把面子放兜里了。

2、QQ群。多加一些相关的网站群,多在群里互动。说不定就能聊出来几个白送的链接。

3、专门的链接网站。现在专门交换友情链接的网站、论坛有很多。像人人学习网,在上方导航栏中就有专门的交换友情链接专区,也可以到像go9go这样专门换友情链接的站找。

4、资源互换。如果实在搞不到链接,只有想办法资源互换了。比如说你的文笔很好,那帮别人写一篇软文,换一篇链接。

5、购买链接。如果上述方法都不行,只有花钱买啦。现在卖链接的很多,价钱也比较透明。一般一个优质的PR5链接,在百元以上,差一点的则是几十元的样子。买链接时注意以下几点:

A、不要一次买太多,容易被K,一点一点的买。

B、不要图便宜买一些质量不好的链接。

C、最好在PR值更新前一个月再买,这样就可以省两个月的钱了。

D、当PR值被带起来以后,赶紧去换一些优质的链接回来。毕竟长期靠花钱买链接,成本也太高了点。

四、相关名字解释

1、什么是外链:外链也叫外部链接,或是反向链接。是指非本地站点以外的链接。凡是外部网站链接自己站点的链接,都称之为外链。

2、什么是PR值:PR值全称为PageRank,网页的级别技术。是Google用于评测一个网页“重要性”的一种方法,级别从1到10级,10级为满分。PR值越高说明该网页越受欢迎(越重要),同时也将在搜索引擎中获得更好的排名。

3、什么是网站权重:搜索引擎给网站(包括网页)赋予一定的权威值,对网站(含网页)权威的评估评价,一个网站权重越高,在搜索引擎所占的份量越大,在搜索引擎排名就越好,提高网站权重,不但利于网站(包括网页)在搜索引擎的排名更靠前,还能提高整站的流量,提高网站信任度所以提高网站的权重是相当重要。

简单的说,权重即网站在SEO中的重要性,权威性。权重不等于排名,但权重对排名有着非常的大影响,整站权重的提高有利于内页的排名。

4、什么是网页快照:通俗的说,网页快照就是搜索引擎在收录网页时,都会做一个备份,大多是文本的,保存了这个网页的主要文字内容,这样当这个网页被删除或连接失效时,用户可以使用网页快照来查看这个网页的主要内容,由于这个快照以文本内容为主,所以会加快访问速度。

5、什么是PR值劫持:也就是用欺骗手段获得工具条上比较高的PR值显示。方法是利用跳转。一般搜索引擎在处理301和302转向的时候,都是把目标URL当作实际应该收录的URL。当然也有特例,不过在大部分情况下是这样处理的。所以如果你从域名A做301或302跳转到域名B,而域名B的PR值比较高,域名A在PR更新后,也会显示域名B的PR值。最简单的就是先做301或302跳转到高PR的域名B,等PR更新过后,立刻取消转向,同时也获得了和B站相同的PR值。这个做假的PR显示值至少维持到下一次PR更新,一般有两三个月或更长的时间(最近GG更新有点慢)。

更隐讳一点的办法是,通过程序检测到Google蜘蛛,返回301或302转向,对普通访问者和其他蜘蛛都返回正常内容。这样我们看到的是普通网站,只有Google会看到转向。

小贴士:本文系推一把创始人、蓝色烽火成员江礼坤原创。转载时请保留此版权信息。

五、花钱购买
花钱购买是最直接而有效的方法,也是最容易控制的方法。但是大家注意,不要去购买黑链、隐藏链等非正常链接。同时也要注意链接的质量,不要只盯着PR看,PR高不一定代表其链接就一定优质。

六、在论坛社区留外链
对于既没有钱,又没有资源的新站来说,通过论坛留外链,是目前最主流的方法。
A、签名里的外链与贴子里的外链,效果是一样的。所以大家不要放着签名不用,非要违反论坛规定,在贴子里留外链。像人人学习论坛,签名是允许留链接的,而且有专门的广告外链区。而且这个区的权重非常高。但是很多会员偏不用这些合法的途径,非要在贴子里留一大堆链接。不管在那个论坛,这样做的后果只有两个:乐观一点的结果是被封号。严重的结果就是网址被对方永久屏蔽。
B、论坛内的外链,属于内容页的链接。这种链接的权重是很低很低的,所以想靠这种链接来提升网站的权重或是关键字的排名,那就需要量非常大才行。注意,这里说的量大,是指发外链的目标论坛要多,而不是指在同一个论坛里大量的发链接。这个大家一定要搞清楚。当然,同一个论坛也不是说发过一个外链贴就OK了,也需要经常发。比如说同一个论坛,一周发个三五个链接就OK,个人感觉一天一条足矣。
C、论坛链接也要细水长流的做,不要忽多忽少。比如今天发了几百上千条外链。然后就不发了,这样搞,就像葛优大爷的脑袋一样,优化的太明显了。搜索引擎闭着眼都知道是咂回事。

七、在问答类网站留链接
问答类的链接,和百科类的效果类似。其实在百科留外链,主要也是为了提升知名度和带流量。但是如果想达到提升名度和提升流量的目的,就需要天天上去回答问题才行。说白了在里面做品牌。但是这个耗费的时间和精力,就太多了。值得不值得这么去投入,就需要大家自己去衡量了。

八、在信息分类网站留链接
现在的信息分类网站很多,全国性的有,比如58、赶集,地方性的也有。所以利用这个方法留外链不错。而且分类信息站不同于论坛,只要不发纯广告,是可以留外链的。比如说最简单的,发布招聘信息,然后留个公司网址。这样的信息,管理员是绝对不会删除的。

九、通过资源留外链
这里说的资源,主要是指网站模板、网站程序、在线工具一类的资源。如果大家有能力开发或是制作这类资源,那恭喜你,你找到了一条留外链的捷径。比如说大家在制作这类资源时,将作者的版权地址加在下面,并且说明,如果谁想免费使用,需要保留作者地址。然后把这些资源免费传播出去。这样就可以坐等收链接了。不过也要注意一下,这个方法也可能会带来一个负面作用,就是突然一下出现很多外链,而被搜索引擎惩罚。

十、所谓的站内链接
排名的最基本单位是网页,没有一般SEO教程中说的外部和内部之分。大家去搜索一个关键词,出来的结果是一个个的网页而不是一个个的网站。很多SEO教程总把网站当作个体来做事情,这是完全错误的。很多人还是不理解这句话,就是“排名的最基本单位是网页”。当你明白“排名的最基本单位是网页”,自然就知道怎么去做外部链接了。

最后说明一点:很多人说反链建设其实可以通过软件群发或者其他类似的手段实现,那么我告诉你你错了,任何一款群发软件所制造的反链都会被列入引擎的黑名单中,即使短时间内不会惩罚到你,但终究有一天会轮到你头上的。所以新手切莫使用群发软件去做反链,那只会伤害到你的网站。