C++ 高级篇(一)—— 模板(Templates)



模板(Templates)是ANSI-C++ 标准中新引入的概念。如果你使用的 C++ 编译器不符合这个标准,则你很可能不能使用模板。

 

 

函数模板( Function templates)

模板(Templates)使得我们可以生成通用的函数,这些函数能够接受任意数据类型的参数,可返回任意类型的值,而不需要对所有可能的数据类型进行函数重载。这在一定程度上实现了宏(macro)的作用。它们的原型定义可以是下面两种中的任何一个:

template <class identifier> function_declaration;
template <typename identifier> function_declaration;

上面两种原型定义的不同之处在关键字class 或 typename的使用。它们实际是完全等价的,因为两种表达的意思和执行都一模一样。

例如,要生成一个模板,返回两个对象中较大的一个,我们可以这样写:

template <class GenericType>

GenericType GetMax (GenericType a, GenericType b) { return (a>b?a:b); }

在第一行声明中,我们已经生成了一个通用数据类型的模板,叫做GenericType。因此在其后面的函数中,GenericType 成为一个有效的数据类型,它被用来定义了两个参数a和 b ,并被用作了函数GetMax的返回值类型。

GenericType 仍没有代表任何具体的数据类型;当函数 GetMax 被调用的时候,我们可以使用任何有效的数据类型来调用它。这个数据类型将被作为pattern来代替函数中GenericType 出现的地方。用一个类型pattern来调用一个模板的方法如下:

function <type> (parameters);

例如,要调用GetMax 来比较两个int类型的整数可以这样写:

int x,y;
GetMax <int> (x,y);

因此,GetMax 的调用就好像所有的GenericType 出现的地方都用int 来代替一样。

这里是一个例子:

// function template

#include <iostream.h>

template <class T> T GetMax (T a, T b) {

    T result;

    result = (a>b)? a : b;

    return (result);

}

int main () {

    int i=5, j=6, k;

    long l=10, m=5, n;

    k=GetMax(i,j);

    n=GetMax(l,m);

    cout << k << endl;

    cout << n << endl;

    return 0;
}

6
10

(在这个例子中,我们将通用数据类型命名为T 而不是 GenericType ,因为T短一些,并且它是模板更为通用的标示之一,虽然使用任何有效的标示符都是可以的。)

在上面的例子中,我们对同样的函数GetMax()使用了两种参数类型:int 和 long,而只写了一种函数的实现,也就是说我们写了一个函数的模板,用了两种不同的pattern来调用它。

如你所见,在我们的模板函数 GetMax() 里,类型 T 可以被用来声明新的对象

T result;

result 是一个T类型的对象, 就像a 和 b一样,也就是说,它们都是同一类型的,这种类型就是当我们调用模板函数时写在尖括号<> 中的类型。

在这个具体的例子中,通用类型 T 被用作函数GetMax 的参数,不需要说明<int>或 <long>,编译器也可以自动检测到传入的数据类型,因此,我们也可以这样写这个例子:

int i,j;
GetMax (i,j);

因为i 和j 都是int 类型,编译器会自动假设我们想要函数按照int进行调用。这种暗示的方法更为有用,并产生同样的结果:

// function template II

#include <iostream.h>

template <class T> T GetMax (T a, T b) {

    return (a>b?a:b);

}

int main () {

    int i=5, j=6, k;

    long l=10, m=5, n;

    k=GetMax(i,j);

    n=GetMax(l,m);

    cout << k << endl;

    cout << n << endl;

    return 0;

}

6
10

注意在这个例子的main() 中我们如何调用模板函数GetMax() 而没有在括号<>中指明具体数据类型的。编译器自动决定每一个调用需要什么数据类型。

因为我们的模板函数只包括一种数据类型 (class T), 而且它的两个参数都是同一种类型,我们不能够用两个不同类型的参数来调用它:

int i;
long l;
k = GetMax (i,l);

上面的调用就是不对的,因为我们的函数等待的是两个同种类型的参数。

我们也可以使得模板函数接受两种或两种以上类型的数据,例如:

template <class T>

T GetMin (T a, U b) { return (a<b?a:b); }

在这个例子中,我们的模板函数 GetMin() 接受两个不同类型的参数,并返回一个与第一个参数同类型的对象。在这种定义下,我们可以这样调用该函数:

int i,j;
long l;
i = GetMin <int, long> (j,l);

或者,简单的用

i = GetMin (j,l);

虽然 j 和 l 是不同的类型。

 

类模板(Class templates)

我们也可以定义类模板(class templates),使得一个类可以有基于通用类型的成员,而不需要在类生成的时候定义具体的数据类型,例如:

template <class T>

class pair {

    T values [2];

public:

    pair (T first, T second) {

        values[0]=first;

        values[1]=second;

    }

};

上面我们定义的类可以用来存储两个任意类型的元素。例如,如果我们想要定义该类的一个对象,用来存储两个整型数据115 和 36 ,我们可以这样写:

pair<int> myobject (115, 36);

我们同时可以用这个类来生成另一个对象用来存储任何其他类型数据,例如:

pair<float> myfloats (3.0, 2.18);

在上面的例子中,类的唯一一个成员函数已经被inline 定义。如果我们要在类之外定义它的一个成员函数,我们必须在每一函数前面加template <... >。

// class templates

#include <iostream.h>

template <class T> class pair {
     T value1, value2;
public:
    pair (T first, T second) {

        value1=first;

        value2=second;

    }

    T getmax ();

};

template <class T>

T pair::getmax (){

    T retval;

    retval = value1>value2? value1 : value2;

    return retval;

}

int main () {

    pair myobject (100, 75);

    cout << myobject.getmax();

    return 0;

}

100

注意成员函数getmax 是怎样开始定义的:

template <class T>
T pair::getmax ()

所有写 T 的地方都是必需的,每次你定义模板类的成员函数的时候都需要遵循类似的格式(这里第二个T表示函数返回值的类型,这个根据需要可能会有变化)。

 

模板特殊化(Template specialization)

模板的特殊化是当模板中的pattern有确定的类型时,模板有一个具体的实现。例如假设我们的类模板pair 包含一个取模计算(module operation)的函数,而我们希望这个函数只有当对象中存储的数据为整型(int)的时候才能工作,其他时候,我们需要这个函数总是返回0。这可以通过下面的代码来实现:

// Template specialization

#include <iostream.h>

template <class T> class pair {

    T value1, value2;

public:

    pair (T first, T second){

        value1=first;

        value2=second;

    }

    T module () {return 0;}

};

template <>

class pair <int> {

    int value1, value2;

public:

    pair (int first, int second){

        value1=first;

        value2=second;

    }

    int module ();

};

template <>

int pair<int>::module() {

    return value1%value2;

}

int main () {

    pair <int> myints (100,75);

    pair <float> myfloats (100.0,75.0);

    cout << myints.module() << '\n';

    cout << myfloats.module() << '\n';

    return 0;

}

25
0

由上面的代码可以看到,模板特殊化由以下格式定义:

template <> class class_name <type>

这个特殊化本身也是模板定义的一部分,因此,我们必须在该定义开头写template <>。而且因为它确实为一个具体类型的特殊定义,通用数据类型在这里不能够使用,所以第一对尖括号<> 内必须为空。在类名称后面,我们必须将这个特殊化中使用的具体数据类型写在尖括号<>中。

当我们特殊化模板的一个数据类型的时候,同时还必须重新定义类的所有成员的特殊化实现(如果你仔细看上面的例子,会发现我们不得不在特殊化的定义中包含它自己的构造函数 constructor,虽然它与通用模板中的构造函数是一样的)。这样做的原因就是特殊化不会继承通用模板的任何一个成员。

 

模板的参数值(Parameter values for templates)

除了模板参数前面跟关键字class 或 typename 表示一个通用类型外,函数模板和类模板还可以包含其它不是代表一个类型的参数,例如代表一个常数,这些通常是基本数据类型的。例如,下面的例子定义了一个用来存储数组的类模板:

// array template

#include <iostream.h>

template <class T, int N>

class array {

    T memblock [N];

public:

    void setmember (int x, T value);

    T getmember (int x);

};

template <class T, int N>

void array<T,N>::setmember (int x, T value) {

    memblock[x]=value;

}

template <class T, int N>

T array<T,N>::getmember (int x) {

    return memblock[x];

}

int main () {

    array <int,5> myints;

    array <float,5> myfloats;

    myints.setmember (0,100);

    myfloats.setmember (3,3.1416);

    cout << myints.getmember(0) << '\n';

    cout << myfloats.getmember(3) << '\n';

    return 0;

}

100
3.1416

我们也可以为模板参数设置默认值,就像为函数参数设置默认值一样。

下面是一些模板定义的例子:

template <class T> // 最常用的:一个class 参数。

template <class T, class U> // 两个class 参数。

template <class T, int N> // 一个class 和一个整数。

template <class T = char> // 有一个默认值。

template <int Tfunc (int)> // 参数为一个函数。

 

模板与多文件工程 (Templates and multiple-file projects)

从编译器的角度来看,模板不同于一般的函数或类。它们在需要时才被编译(compiled on demand),也就是说一个模板的代码直到需要生成一个对象的时候(instantiation)才被编译。当需要instantiation的时候,编译器根据模板为特定的调用数据类型生成一个特殊的函数。

当工程变得越来越大的时候,程序代码通常会被分割为多个源程序文件。在这种情况下,通常接口(interface)和实现(implementation)是分开的。用一个函数库做例子,接口通常包括所有能被调用的函数的原型定义。它们通常被定义在以.h 为扩展名的头文件 (header file) 中;而实现 (函数的定义) 则在独立的C++代码文件中。

模板这种类似宏(macro-like) 的功能,对多文件工程有一定的限制:函数或类模板的实现 (定义) 必须与原型声明在同一个文件中。也就是说我们不能再 将接口(interface)存储在单独的头文件中,而必须将接口和实现放在使用模板的同一个文件中。

回到函数库的例子,如果我们想要建立一个函数模板的库,我们不能再使用头文件(.h) ,取而代之,我们应该生成一个模板文件(template file),将函数模板的接口和实现 都放在这个文件中 (这种文件没有惯用扩展名,除了不要使用.h扩展名或不要不加任何扩展名)。在一个工程中多次包含同时具有声明和实现的模板文件并不会产生链接错误 (linkage errors),因为它们只有在需要时才被编译,而兼容模板的编译器应该已经考虑到这种情况,不会生成重复的代码。

模板(Templates)是ANSI-C++ 标准中新引入的概念。如果你使用的 C++ 编译器不符合这个标准,则你很可能不能使用模板。

 

 

函数模板( Function templates)

模板(Templates)使得我们可以生成通用的函数,这些函数能够接受任意数据类型的参数,可返回任意类型的值,而不需要对所有可能的数据类型进行函数重载。这在一定程度上实现了宏(macro)的作用。它们的原型定义可以是下面两种中的任何一个:

template <class identifier> function_declaration;
template <typename identifier> function_declaration;

上面两种原型定义的不同之处在关键字class 或 typename的使用。它们实际是完全等价的,因为两种表达的意思和执行都一模一样。

例如,要生成一个模板,返回两个对象中较大的一个,我们可以这样写:

template <class GenericType>

GenericType GetMax (GenericType a, GenericType b) { return (a>b?a:b); }

在第一行声明中,我们已经生成了一个通用数据类型的模板,叫做GenericType。因此在其后面的函数中,GenericType 成为一个有效的数据类型,它被用来定义了两个参数a和 b ,并被用作了函数GetMax的返回值类型。

GenericType 仍没有代表任何具体的数据类型;当函数 GetMax 被调用的时候,我们可以使用任何有效的数据类型来调用它。这个数据类型将被作为pattern来代替函数中GenericType 出现的地方。用一个类型pattern来调用一个模板的方法如下:

function <type> (parameters);

例如,要调用GetMax 来比较两个int类型的整数可以这样写:

int x,y;
GetMax <int> (x,y);

因此,GetMax 的调用就好像所有的GenericType 出现的地方都用int 来代替一样。

这里是一个例子:

// function template

#include <iostream.h>

template <class T> T GetMax (T a, T b) {

    T result;

    result = (a>b)? a : b;

    return (result);

}

int main () {

    int i=5, j=6, k;

    long l=10, m=5, n;

    k=GetMax(i,j);

    n=GetMax(l,m);

    cout << k << endl;

    cout << n << endl;

    return 0;
}

6
10

(在这个例子中,我们将通用数据类型命名为T 而不是 GenericType ,因为T短一些,并且它是模板更为通用的标示之一,虽然使用任何有效的标示符都是可以的。)

在上面的例子中,我们对同样的函数GetMax()使用了两种参数类型:int 和 long,而只写了一种函数的实现,也就是说我们写了一个函数的模板,用了两种不同的pattern来调用它。

如你所见,在我们的模板函数 GetMax() 里,类型 T 可以被用来声明新的对象

T result;

result 是一个T类型的对象, 就像a 和 b一样,也就是说,它们都是同一类型的,这种类型就是当我们调用模板函数时写在尖括号<> 中的类型。

在这个具体的例子中,通用类型 T 被用作函数GetMax 的参数,不需要说明<int>或 <long>,编译器也可以自动检测到传入的数据类型,因此,我们也可以这样写这个例子:

int i,j;
GetMax (i,j);

因为i 和j 都是int 类型,编译器会自动假设我们想要函数按照int进行调用。这种暗示的方法更为有用,并产生同样的结果:

// function template II

#include <iostream.h>

template <class T> T GetMax (T a, T b) {

    return (a>b?a:b);

}

int main () {

    int i=5, j=6, k;

    long l=10, m=5, n;

    k=GetMax(i,j);

    n=GetMax(l,m);

    cout << k << endl;

    cout << n << endl;

    return 0;

}

6
10

注意在这个例子的main() 中我们如何调用模板函数GetMax() 而没有在括号<>中指明具体数据类型的。编译器自动决定每一个调用需要什么数据类型。

因为我们的模板函数只包括一种数据类型 (class T), 而且它的两个参数都是同一种类型,我们不能够用两个不同类型的参数来调用它:

int i;
long l;
k = GetMax (i,l);

上面的调用就是不对的,因为我们的函数等待的是两个同种类型的参数。

我们也可以使得模板函数接受两种或两种以上类型的数据,例如:

template <class T>

T GetMin (T a, U b) { return (a<b?a:b); }

在这个例子中,我们的模板函数 GetMin() 接受两个不同类型的参数,并返回一个与第一个参数同类型的对象。在这种定义下,我们可以这样调用该函数:

int i,j;
long l;
i = GetMin <int, long> (j,l);

或者,简单的用

i = GetMin (j,l);

虽然 j 和 l 是不同的类型。

 

类模板(Class templates)

我们也可以定义类模板(class templates),使得一个类可以有基于通用类型的成员,而不需要在类生成的时候定义具体的数据类型,例如:

template <class T>

class pair {

    T values [2];

public:

    pair (T first, T second) {

        values[0]=first;

        values[1]=second;

    }

};

上面我们定义的类可以用来存储两个任意类型的元素。例如,如果我们想要定义该类的一个对象,用来存储两个整型数据115 和 36 ,我们可以这样写:

pair<int> myobject (115, 36);

我们同时可以用这个类来生成另一个对象用来存储任何其他类型数据,例如:

pair<float> myfloats (3.0, 2.18);

在上面的例子中,类的唯一一个成员函数已经被inline 定义。如果我们要在类之外定义它的一个成员函数,我们必须在每一函数前面加template <... >。

// class templates

#include <iostream.h>

template <class T> class pair {
     T value1, value2;
public:
    pair (T first, T second) {

        value1=first;

        value2=second;

    }

    T getmax ();

};

template <class T>

T pair::getmax (){

    T retval;

    retval = value1>value2? value1 : value2;

    return retval;

}

int main () {

    pair myobject (100, 75);

    cout << myobject.getmax();

    return 0;

}

100

注意成员函数getmax 是怎样开始定义的:

template <class T>
T pair::getmax ()

所有写 T 的地方都是必需的,每次你定义模板类的成员函数的时候都需要遵循类似的格式(这里第二个T表示函数返回值的类型,这个根据需要可能会有变化)。

 

模板特殊化(Template specialization)

模板的特殊化是当模板中的pattern有确定的类型时,模板有一个具体的实现。例如假设我们的类模板pair 包含一个取模计算(module operation)的函数,而我们希望这个函数只有当对象中存储的数据为整型(int)的时候才能工作,其他时候,我们需要这个函数总是返回0。这可以通过下面的代码来实现:

// Template specialization

#include <iostream.h>

template <class T> class pair {

    T value1, value2;

public:

    pair (T first, T second){

        value1=first;

        value2=second;

    }

    T module () {return 0;}

};

template <>

class pair <int> {

    int value1, value2;

public:

    pair (int first, int second){

        value1=first;

        value2=second;

    }

    int module ();

};

template <>

int pair<int>::module() {

    return value1%value2;

}

int main () {

    pair <int> myints (100,75);

    pair <float> myfloats (100.0,75.0);

    cout << myints.module() << '\n';

    cout << myfloats.module() << '\n';

    return 0;

}

25
0

由上面的代码可以看到,模板特殊化由以下格式定义:

template <> class class_name <type>

这个特殊化本身也是模板定义的一部分,因此,我们必须在该定义开头写template <>。而且因为它确实为一个具体类型的特殊定义,通用数据类型在这里不能够使用,所以第一对尖括号<> 内必须为空。在类名称后面,我们必须将这个特殊化中使用的具体数据类型写在尖括号<>中。

当我们特殊化模板的一个数据类型的时候,同时还必须重新定义类的所有成员的特殊化实现(如果你仔细看上面的例子,会发现我们不得不在特殊化的定义中包含它自己的构造函数 constructor,虽然它与通用模板中的构造函数是一样的)。这样做的原因就是特殊化不会继承通用模板的任何一个成员。

 

模板的参数值(Parameter values for templates)

除了模板参数前面跟关键字class 或 typename 表示一个通用类型外,函数模板和类模板还可以包含其它不是代表一个类型的参数,例如代表一个常数,这些通常是基本数据类型的。例如,下面的例子定义了一个用来存储数组的类模板:

// array template

#include <iostream.h>

template <class T, int N>

class array {

    T memblock [N];

public:

    void setmember (int x, T value);

    T getmember (int x);

};

template <class T, int N>

void array<T,N>::setmember (int x, T value) {

    memblock[x]=value;

}

template <class T, int N>

T array<T,N>::getmember (int x) {

    return memblock[x];

}

int main () {

    array <int,5> myints;

    array <float,5> myfloats;

    myints.setmember (0,100);

    myfloats.setmember (3,3.1416);

    cout << myints.getmember(0) << '\n';

    cout << myfloats.getmember(3) << '\n';

    return 0;

}

100
3.1416

我们也可以为模板参数设置默认值,就像为函数参数设置默认值一样。

下面是一些模板定义的例子:

template <class T> // 最常用的:一个class 参数。

template <class T, class U> // 两个class 参数。

template <class T, int N> // 一个class 和一个整数。

template <class T = char> // 有一个默认值。

template <int Tfunc (int)> // 参数为一个函数。

 

模板与多文件工程 (Templates and multiple-file projects)

从编译器的角度来看,模板不同于一般的函数或类。它们在需要时才被编译(compiled on demand),也就是说一个模板的代码直到需要生成一个对象的时候(instantiation)才被编译。当需要instantiation的时候,编译器根据模板为特定的调用数据类型生成一个特殊的函数。

当工程变得越来越大的时候,程序代码通常会被分割为多个源程序文件。在这种情况下,通常接口(interface)和实现(implementation)是分开的。用一个函数库做例子,接口通常包括所有能被调用的函数的原型定义。它们通常被定义在以.h 为扩展名的头文件 (header file) 中;而实现 (函数的定义) 则在独立的C++代码文件中。

模板这种类似宏(macro-like) 的功能,对多文件工程有一定的限制:函数或类模板的实现 (定义) 必须与原型声明在同一个文件中。也就是说我们不能再 将接口(interface)存储在单独的头文件中,而必须将接口和实现放在使用模板的同一个文件中。

回到函数库的例子,如果我们想要建立一个函数模板的库,我们不能再使用头文件(.h) ,取而代之,我们应该生成一个模板文件(template file),将函数模板的接口和实现 都放在这个文件中 (这种文件没有惯用扩展名,除了不要使用.h扩展名或不要不加任何扩展名)。在一个工程中多次包含同时具有声明和实现的模板文件并不会产生链接错误 (linkage errors),因为它们只有在需要时才被编译,而兼容模板的编译器应该已经考虑到这种情况,不会生成重复的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java笔试之Singleton

单例模式的出现&#xff0c;其主要的目的是为了使一个类只有一个实例存在。 实现单例模式主要有两种方式&#xff08;我所知道的&#xff09; 饿汉式&#xff1a;不管有没有需要&#xff0c;都在内部先new出一个实例public class Singleton{//私有的默认构造子 private Single…

Linux--文件结构体struct file

代码:struct file {   struct file *f_next&#xff0c;**f_pprev;   struct dentry *f_dentry;   struct file_operations *f_op;   mode_t f_mode;   loff_t f_pos;   unsigned int f_count&#xff0c;f_flags;   unsigned long f_reada&#xff0c;f_…

PPT到底是天使还是魔鬼?

说老实话&#xff0c;我非常不喜欢那些PPT的培训者一味地鼓吹PPT的重要性&#xff0c;视觉化思维的重要性&#xff0c;PPT在演讲中的重要性等等&#xff0c;我很清楚他们这么说是因为他们必须这么说&#xff0c;因为如果不把PPT的重要性强调一下&#xff0c;谁来上他的课呢&…

ultraedit正则表达式

一般使用ultraedit中的Perl风格的正则表达式&#xff0c;下面是perl正则的基本语法 perl中的元字符如下&#xff1a; ^ 表示一行的开头&#xff1b; $ 表示一行的结尾&#xff1b; ( ) 表示一个匹配块的&#xff0c;可以对匹配上的块通过$1,$2...进行读取&#xff0c;…

微软云介绍

微软云介绍 http://msdn.microsoft.com/zh-cn/ff380142 什么是云开发&#xff1f;&#xff08;概述&#xff09; 云计算是指远程运行并通过 Internet 访问的计算机和应用程序。在云计算中&#xff0c;虚拟机在大型数据中心中运行&#xff0c;并取代了物理 PC 和服务器。通过将许…

IO端口和IO内存的区别及分别使用的函数接口

IO端口和IO内存的区别及分别使用的函数接口 每个外设都是通过读写其寄存器来控制的。外设寄存器也称为I/O端口&#xff0c;通常包括&#xff1a;控制寄存器、状态寄存器和数据寄存器三大类。根据访问外设寄存器的不同方式&#xff0c;可以把CPU分成两大类。一类CPU&#xff08…

DHCP服务开启了,为什么老是网络冲突

<b><a target"_blank" href"http://www.hnbkhb.com/ " >河南</a><a target"_blank" href"http://www.hnzzfk.com/ " >河南</a><a target"_blank" href"http://www.0371fkyy.com/ &qu…

Linux进程状态解析之R、S、D、T、Z、X

Linux进程状态解析之R、S、D、T、Z、X&#xff1b;Linux是一个多用户&#xff0c;多任务的系统&#xff0c;可以同时运&#xff1b;众所周知&#xff0c;现在的分时操作系统能够在一个CPU上运&#xff1b;在linux系统中&#xff0c;每个被运行的程序实例对应一个&#xff1b;Li…

Win8 HTML5与JS编程学习笔记(二)

近期一直受到win8应用的Grid布局困扰&#xff0c;经过了半下午加半个晚上的奋斗&#xff0c;终于是弄明白了Grid布局方法的规则。之前我是阅读的微软官方的开发教程&#xff0c;书中没有详细说明CSS3的布局规则&#xff0c;自己鼓捣了半天也是一头雾水&#xff0c;于是又找到了…

flsah的分类

1. flash按照内部存储结构不同&#xff0c;分为两种&#xff1a;nor flash和nand flash。 nor flash&#xff1a;像访问SDRAM一样&#xff0c;按照数据/地址总线直接访问, 可写的次数较少&#xff0c;速度也慢&#xff0c;由于其读时序类似于SRAM&#xff0c;读地址是线性结构&…

Oracle EXP/IMP参数详解

exp/imp是Oracle自带的导入导出命令&#xff0c;运用它&#xff0c;即使不需要那结UI工具也能轻易的完成数据导出导入工作&#xff0c;下面是它们的参数&#xff1a;EXP参数详解使用的格式是&#xff1a;EXP KEYWORDvalue 或 KEYWORD(value1,value2,...,valueN)其中USERID是必须…

java每日小算法(10)

/*【程序10】 题目&#xff1a;一球从100米高度自由落下&#xff0c;每次落地后反跳回原高度的一半&#xff1b;再落下&#xff0c;求它在 第10次落地时&#xff0c;共经过多少米&#xff1f;第10次反弹多高&#xff1f; */ package test;public class test {public static vo…

C语言串口驱动程序

驱动层屏蔽了硬件细节&#xff0c;个人猜测&#xff0c;几乎所有移植好的系统的串口&#xff0c;都可以用一样的代码来操作&#xff0c;至少2440和树莓派是通用的。 分享代码如下&#xff1a; [cpp] view plaincopy #include <sys/types.h> #include <sys/stat.h>…

Windows下的Qt Creator的安装

采用Qt和Qt creator分别下载和安装的方式&#xff1a;&#xff08;需要手动设置关联Qt和Qt Creator&#xff09; 一、软件下载 从http://qt-project.org/downloads分别下载Qt和Qt Creator&#xff1a; Qt使用4.7.2版本&#xff1a;qt-win-opensource-4.7.2-mingw.exe Qt Creato…

进程 、进程组、会话、控制终端之间的关系

一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的&#xff0c;他们彼此之间或者存在者父子、兄弟关系&#xff0c;或者在功能有相近的联系。 那linux为什么要有进程组呢&#xff1f;其实提供进程组就是方便管理这些进程。假设要完成一个任务&#xff0c;需要同时并…

matlab保存数据

一&#xff1a;存txt文件&#xff0c;用dlmwrite()dlmwrite 将一个矩阵写到由分隔符分割的文件中。 在保存整数到文件时使用save存为ascii文件时&#xff0c;常常是文件里都是实型格式的数据&#xff08;有小数点&#xff0c;和后面很多的0&#xff0c;看着很不方便&#xff09…

linux下串口的阻塞和非阻塞操作

有两个可以进行控制串口阻塞性&#xff08;同时控制read和write&#xff09;&#xff1a;一个是在打开串口的时候&#xff0c;open函数是否带O_NDELAY&#xff1b;第二个是可以在打开串口之后通过fcntl()函数进行控制。 阻塞的定义&#xff1a; 对于read&#xff0c;block指当串…

串口初始化配置

在基于AT91的嵌入式linux中接收串口数据时&#xff0c;发现对于接收的数据经常出现接收不完整的现象。一帧的数据可能会被当做两帧接收&#xff0c;导致对于一帧数据接收出现问题。虽然这种情况在一般情况下&#xff0c;并不是经常出现&#xff0c;但是只要数据量稍微大一些&am…

Angularjs 通过asp.net web api认证登录

Angularjs 通过asp.net web api认证登录 Angularjs利用asp.net mvc提供的asp.net identity&#xff0c;membership实现居于数据库的用户名/密码的认证登录 环境 Vs.net 2013 Asp.net mvc web api Individual user accounts Angularjs Underscore 新建一个asp.net mvc web api …

PANIC: Unreachable code reached.

为什么80%的码农都做不了架构师&#xff1f;>>> Caused by: java.lang.RuntimeException: PANIC: Unreachable code reached.at cryptix.jce.provider.cipher.BlockCipher.engineGetParameters(BlockCipher.java:244)at javax.crypto.Cipher.checkCryptoPerm(Ciphe…