C++基础知识总结

不管是自我定位太高,还是职位层次太低,系统复习了一遍很久没有摸过的C++总是有好处的。总结如下:

一、new和malloc的区别

1、new和delete配对,释放数组需要用delete[]。new和delete实际上调用了malloc和free,另外调用了类的构造函数和析构函数。
2、malloc和free配对,malloc返回的是void指针,需要强转。

3、new申请的内存保存在堆中,malloc申请的内存保存在自由存储区。

二、C++运算符

1、取模操作符:%
2、逻辑否、与、或:!, &&, ||
3、三元操作符:
  c = (a>b) ? a : b;
4、按位与、或、非
  & AND 逻辑与 Logic AND
  | OR 逻辑或Logic OR
  ~ NOT 对1取补(位反转)Complement to one (bit inversion)
5、按位移:
  << SHL 左移Shift Left
  >> SHR 右移Shift Right

三、&: 取地址运算符、定义变量引用

&操作符用于取地址时的用法是:int* x=&y;。

然而,另外一种用法是定义变量别名,这种用法不能和取地址简单等同。用于传递函数输入参数时很好理解,但定义变量时容易引起理解错误,特别是和指针的区别:

从内存的角度看,指针和引用是完全不同的。指针,内存要为它分配一个存储空间。引用,内存不分配空间的,引用只是一个别名。我认为就是在符号表里增加一个标志而已,对于语句int &y=x; (&x=&y)为true。

实际上“引用”可以做的任何事情“指针”也都能够做,为什么还要“引用”这东西?答案是“用适当的工具做恰如其分的工作”。当重载某个操作符时,你应该使用引用。最普通的例子是操作符[]。这个操作符典型的用法是返回一个目标对象,其能被赋值。如果操作符[]返回一个指针,那么后一个语句就得这样写:

 *v[5] = 10;

但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。

引用的一些规则如下:

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化),否则会报编译错误。 
(2)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。 
    以下示例程序中,k被初始化为i的引用。语句k = j并不能将k 修改成为j 的引用,只是把k的值改变成为6。由于k是i的引用,所以i 的值也变成了6。

  int i = 5;
  int j = 6;
  int &k = i;
  k = j; // k 和i 的值都变成了6;

(3)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。 
    以下的写法将地址指向一个位置的内存,是错误的。结果将是不确定的(编译器能产生一些输出,导致任何事情都有可能发生)

  char *pc = 0; // 设置指针为空值
  char& rc = *pc; // 让引用指向空值

(4)“sizeof 引用”得到的是所指向的变量(对象)的大小,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。

(5)引用只能指向一个实际的变量,不能指向指针或引用
   (int*) * p1; // p1是指针的指针
   (int*) & p2; // p2是指向整型指针的引用
   引用不能指向指针或引用!
   (int&) * p3; // ERROR: 不能有指向引用的指针,因为引用只是一个别名
   (int&) & p4; // ERROR: 不能有指向引用的引用,因为引用只是一个别名
(6)指针和引用在内部的实现其实是没多大的区别的。但使用时有些地方是要注意的。因为引用具有对象行为,这一点很重要。引用复制时会调用对象的复制函数,在涉及多态时,这地方很容易出错。

  class A{...};
  class B:public A{...};
  void f(A&a1,A&a2)
  {
   a1=a2;//此处调用的只有基类A的复制函数,而B部分不会被进行复制,之将导致数据的不一致(即B部分的数据没有被复制);
   a1.fun();
  }

四、关于const

一般的const变量:

下面两个声明都指向一个const int类型的指针,指针所指向的内存不能被修改,但指针可以指向另一个内存:
  const int *p; 
  int const *q; 
int类型的const指针应该这样声明。指针所指向的内存可以被修改,但指针不能指向另一个内存
  int * const r= &n;

声明一个指向const int类型的const指针:
  const int * const p=&n;

const在函数声明中的含义:

const int& SetPoint(const int& param) const
第一个const:
函数的返回值限定为const,即返回值不能被修改。const int a=SetPoint(...)  a在此之后便不能被修改。
第二个const:
指函数的形参为const类型,函数体内不能被修改.
第三个const:
表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

类的const和static成员变量的初始化:

对于static成员变量,如果同时是const的,可以在类定义中初始化,否则只能在类定义外部初始化。
非static的const成员变量只能在构造函数的初始化列表中初始化。(ClassName():m_1(1){};)

五、一些数据类型和变量赋值语法

1、union 中的所有被声明的元素占据同一段内存空间,其大小取声明中最长的元素的大小。union 的用途之一是将一种较长的基本类型与由其它比较小的数据类型组成的结构(structure)或数组(array)联合使用。
2、long double和float变量的赋值方法:
  3.14159L // long double
  6.02e23f // float
3、容易引起理解错误的定义语句:int*  p,q; 
   第一眼看去,好像是p和q都是int*类型的,但事实上,只有p是一个指针,而q是一个最简单的int型变量。同时定义两个指针的语法是:int *p1, *p2;

4、定义一个指向int[4]数组的指针变量
   int (*p)[4]=RollNum;
   这里,p被声明为一个指向一个4元素(int类型)数组的指针。
5、未指定size情况下,char数组的大小由初始化字符串决定:
   我们可以用下面两种方法的任何一种来初始化字符串mystring:
   char mystring [ ] = { 'H', 'e', 'l', 'l', 'o', '/0' };
   char mystring [ ] = "Hello";
  在两种情况下字符串或数组mystring都被定义为6个字符长(元素类型为字符char):组成Hello的5个字符加上最后的空字符('/0')。在第二种用双引号的情况下,空字符('/0')是被自动加上的。两种情况下sizeof应该都是6,strlen都是5。

六、常用的几个标准C++函数

1、cout和cin的用法:
  cout << "xxx" << endl;
  cin >> "yyy";

2、常用的字符串函数:
  strcat //字符串拼接
  strcpy
  strncpy
  strcmp //字符串比较,相同返回0

七、switch-case的写法

 switch (expression)
 {
  case constant1:
   block of instructions 1
   break;
  case constant2:
   block of instructions 2
   break;
  .
  .
  .
  default:
   default block of instructions
 }

八、函数的几个属性和用法

1、指定函数的默认参数值
int divide (int a, int b=2) {

2、什么是函数重载(Overloaded functions)
两个不同的函数可以用同样的名字,只要它们的参量(arguments)的原型(prototype)不同,也就是说你可以把同一个名字给多个函数,如果它们用不同数量的参数,或不同类型的参数。

3、内联函数

inline 指令可以被放在函数声明之前,要求该函数必须在被调用的地方以代码形式被编译。这相当于一个宏定义(macro)。它的好处只对短小的函数有效,这种情况下因为避免了调用函数的一些常规操作的时间(overhead),如参数堆栈操作的时间,所以编译结果的运行代码会更快一些。
调用函数的时候并不需要写关键字inline ,只有在函数声明前需要写。

4、将数组作为参数传入函数,传的是引用而不是值。
  void procedure (int myarray[ ][3][4])

九、函数指针的用法

使用函数指针的几种方法:
(1)简单调用函数指针;

 void (*pfunc)(int);
 pfunc=callback_funcname;
 callback_funcname(1);

其中声明函数指针原型的代码可以在调用处写,也可以写成全局的。这种方法使用简单,适用于临时调用。
(2)使用typedef调用函数指针:

 typedef void(*PFUNC)(int);
 PFUNC pfunc;
 pfunc=callback_funcname;
 callback_funcname(1);

这种方法适用于多次调用,先全局定义PFUNC,再在每个调用的地方声明临时变量后调用。
(3)C++类中调用成员函数指针(不使用typedef):

 void (*MyClass::pfunc)(int);
 pfunc=&MyClass::callback_funcname;
 (this->*callback_funcname)(1);

和方法1类似,注意语法的不同。
(4)C++类中调用成员函数指针(使用用typedef):

 typedef void(*PFUNC)(int); //在类中typedef
 PUNC pfunc;
 pfunc=&MyClass::callback_funcname;
 (this->*callback_funcname)(1);

和方法2类似,注意语法的不同。

十、typedef的不常用用法

typedef的一般用法是:

typedef int UINT32;

但用来定义一个数组类型或指针函数时,比较特殊:

typedef char CARRAY[32]; //定义了一个CARRAY的类型,代表char[32]

typedef void(*PFUN)(int); //定义了一个指向指针函数的变量类型,函数原型为void xxx(int yyy);

十一、类的private/protected/public属性

1、类的成员如果没有指定访问域,默认是private的。

2、标识符protected 与 private类似,它们的唯一区别在继承时才表现出来。当定义一个子类的时候,基类的protected 成员可以被子类的其它成员所使用,然而private 成员就不可以。

3、public/protected/private继承的区别:
(1)public继承:父类的public依然是public,protected依然是protected,private不可访问;
(2)protected继承:父类的public称为protected,protected称为private;
(3)private继承:父类的所有成员全部变成private。

十二、关于空类

编译器为一个空类提供哪些默认函数?

1、C++编译器会提供默认的构造函数,析构函数, 拷贝构造函数和拷贝赋值操作符(请参考著名的Effective C++的第三版的第5条)
当我们定义一个class而没有明确定义构造函数的时候,编译器会自动假设两个重载的构造函数 (默认构造函数"default constructor" 和复制构造函数"copy constructor")。拷贝构造函数是一个只有一个参数的构造函数(原型:ClassName(ClassName &cn){};),该参数是这个class的一个对象,这个函数的功能是将被传入的对象(object)的所有非静态(non-static)成员变量的值都复制给自身这个object。
必须注意:这两个默认构造函数(empty construction 和 copy constructor )只有在没有其它构造函数被明确定义的情况下才存在。
一个类包含一个对赋值操作符assignation operator (=)的默认定义,该操作符用于两个同类对象之间。这个操作符将其参数对象(符号右边的对象) 的所有非静态 (non-static) 数据成员复制给其左边的对象。
2、用class obj;的方式声明一个对象,如果构造函数没有参数,或只有默认构造函数,后面不能加(),因为编译器会误以为这是一个没有参数的函数声明;
3、如果任何其它有任意参数的构造函数被定义了,默认构造函数和拷贝构造函数就都不存在了。在这种情况下,如果你想要有empty construction和copy constructor ,就必需要自己定义它们。
4、对基本类型,在c++里面,为了模板template,规定他们可以使用类似于类的默认构造函数的方式(仅仅是类似的方式而已) 赋初始值0。这叫做基本类型的显示初始化, 请参考 C++标准程序库(The C++ Standard Library)的14页,2.2.2 基本型别的显示初始化,书中举的例子就是
int i1;//未初始化
int i2 = int(); //初始化为0

sizeof一个空类等于多少?

sizeof一个空类返回1。所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。C++编译器不允许对象为零长度。试想一个长度为0的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。如果有自定义的变量,变量将取代这个缺省成员。

十三、继承或多重继承情况下构造函数的调用顺序

(1)如果声明为Derive: public Super1, public Super2{AnotherClass m_obj;}; 构造函数的调用顺序是:Super1, Super2, AnotherClass, Derive.
(2)如果父类有默认构造函数,或没有参数的构造函数,不需要在子类的构造函数定义中显式调用父类构造函数,否则需要调用。成员对象也是一样道理。以上面的例子说明,Derive的构造函数写法是:
Derive(int i): Super1(i), Super2(i), m_obj(1){...}
注意,成员对象初始化时应该指明对象名称,而不是类名。

析构函数的调用顺序应该是依次反过来的。

十四、虚函数、纯虚函数和抽象类、虚析构函数

虚函数的作用和运行原理

(1)多态是面向对象编程中的核心概念,就是说一个基类类型的指针实际上可能指向的是一个子类对象。只有在运行时才能根据实际情况来决定执行哪个函数,也就是动态联编。和动态联编对应的是静态联编,也就是说在编译时就决定了调用哪个函数。为了实现动态联编,必须将父类的函数声明为virtual。如果没有声明为virtual,可能得到的结果不是预期中的。
对于析构函数而言,虚函数保证子类和父类的析构函数都会被执行。

(2)对于包含了至少一个虚函数的类(或其父类包含虚函数),编译器需要为这个类增加4个字节,用来保存指向虚函数表VTABLE的指针。

纯虚函数和抽象类

包含了纯虚函数的类不能被直接实例化,可以称为抽象类。定义方法:
virtual void func()=0;
子类override一个虚函数,不一定要加virtual关键字。

什么情况下需要指定析构函数为virtual?

(1)析构函数不一定需要定义为虚函数,只有当这个类要作为其他类的父类使用时,才需要定义为虚函数。如果父类的析构函数没有定义为虚函数,则子类对象销毁时,父类析构函数不会被调用。
(2)对于一个抽象类,析构函数可以被定义为纯虚的。
(3)父类和子类之间的虚函数动态联编不会因为private发生影响。
(4)一个类的虚函数在它自己的构造函数和析构函数中被调用的时候,它们就变成普通函数了,不“虚”了。也就是说不能在构造函数和析构函数中让自己“多态”。
(5)在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样。

十五、多重继承情况下如何引用父类的同名成员?

重继承情况下,如果多个基类有同名成员,引用方法是:

pDeriveObj->BaseClass1::Member;

十六、运算符重载

语法:

Type Type::operator +(const Type &i){}

十七、友元

友元可以实现外部对private和protected成员的访问。有两种实现:
(1)友元函数。语法:在函数声明前加上friend。友元函数并不是类的成员函数,实现函数体或调用函数时不加ClassName::。
(2)友元类。在类的声明中加入:friend class VisitorClass;
友元不会被子类继承。

十八、模板

函数模板

实现语法:

在函数的声明和实现前加上template<typename T> ,(typename和class等价),可以写在一行里面,也可以分成两行写,注意>后面没有分号。如果声明和实现分开写,两个地方都要写上template<typename T>。

(1)一行代码中同时声明并实现函数
template <typename T>void func(T t1, T t2)

{...};
(2)分两行代码声明并实现函数
template <class T>
void func(T t1, T t2)
{...};
(3)在两个地方分别声明和实现函数
template <class T>
void func(T t1, T t2);
...
template <class T>
void func(T t1, T t2)
{...}

引用语法:

func<int>(5, 6);

类模板

声明方法:

类模板可以实现在一个类中有一个通用类型的成员变量。

template <class T> class ClassName

{public:

T *m_pVariable;

};

引用方法:

ClassName<int> obj;

模板特殊化

模板特殊化可以专门为某种数据类型定义特殊的行为。类的定义必须和通用的模板类完全一致,除了用专门语法,并将T修改为专门的类型,并定义特殊行为。
template<> class<int>{定义通用函数,定义特殊函数};

定义模板的默认值
template <class T = char> // 有一个默认值。

模板的参数值

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

二十、类型转换和C++高级类型转换

基本类型强转有两种写法:

 int i;
 float f = 3.14;
 i = (int) f;
 i = int ( f );

高级类型转换

ANSI-C++ 标准定义了4种新的类型转换操作符: reinterpret_cast, static_cast, dynamic_cast 和const_cast。

reinterpret_cast可以将一个指针转换为任意其它类型的指针。
ClassA* pa;
ClassB* pb=reinterpret_cast<ClassB*>pa;

static_cast可以执行所有能够隐含执行的类型转换,以及它们的反向操作(即使这种方向操作是不允许隐含执行的)。用于类的指针,也就是说,它允许将一个引申类的指针转换为其基类类型(这是可以被隐含执行的有效转换),同时也允许进行相反的转换:将一个基类转换为一个引申类类型。不会检查被转换的基类是否真正完全是目标类型的。
Derive* pa;
Super* pb;
pa = static_cast<Derive*> pb;
pb = static_cast<Super*> pa;
static_cast除了能够对类指针进行操作,还可以被用来进行类中明确定义的转换,以及对基本类型的标准转换:
double d=3.14159265;
int i = static_cast<int>(d);

dynamic_cast 完全被用来进行指针的操作。它可以用来进行任何可以隐含进行的转换操作以及它们被用于多态类情况下的方向操作。然而与static_cast不同的是, dynamic_cast 会检查后一种情况的操作是否合法,也就是说它会检查类型转换操作是否会返回一个被要求类型的有效的完整的对象。
在不合法的情况下,如果用于指针,将返回NULL;如果用于引用,抛出异常。
Derive* pa = new Derive();
Super* pb = new Super();
pa = dynamic_cast<Derive*> pb; //失败,返回NULL
pb = dynamic_cast<Super*> pa;  //成功

const_cast类型转换对常量const 进行设置或取消操作。
class C {};
const C * a = new C;
C * b = const_cast<C*> (a);

typeid (object_pointer)
这个操作符返回一个类型为type_info的常量对象指针,这种类型定义在标准头函数中。type_info::name()返回对象的类名。

二十一、命名空间

定义一个命名空间:

namespace ns1{...}

设置默认命名空间:

using namespace ns1;

引用其他命名空间的类型:

ns2::variable = xx;

二十二、预处理命令

#undef 完成与 #define相反的工作,它取消对传入的参数的宏定义

#ifdef, #ifndef, #if, #endif, #else and #elif

指令#line 可以使我们对这两点进行控制,也就是说当出错时显示文件中的行数以及我们希望显示的文件名。它的格式是:
#line number "filename"
下面这段代码将会产生一个错误,显示为在文件"assigning variable", line 1 。
#line 1 "assigning variable"
int a?;

这个指令将中断编译过程并返回一个参数中定义的出错信息
#error

这个指令是用来对编译器进行配置的,针对你所使用的平台和编译器而有所不同。
#pragma

二十三、预定义宏

__LINE__ 整数值,表示当前正在编译的行在源文件中的行数。
__FILE__ 字符串,表示被编译的源文件的文件名。
__DATE__ 一个格式为 "Mmm dd yyyy" 的字符串,存储编译开始的日期。
__TIME__ 一个格式为 "hh:mm:ss" 的字符串,存储编译开始的时间。
__cplusplus 整数值,所有C++编译器都定义了这个常量为某个值。如果这个编译器是完全遵守C++标准的,它的值应该等于或大于199711L,具体值取决于它遵守的是哪个版本的标准。

(0)

相关推荐

  • C++基础知识实例解析(一)

    今天小编和大家一起通过几个实例学习C++基础知识,下面进行实例解析: [1-1]编写一个程序,实现一个整数.长整数.浮点数和双精度数除以2的计算. [分析]这是一个典型的函数重载的程序.声明函数div()为除法函数,每个函数的功能基本都是一致的,不同的只是形式参数的类型不同而已.程序代码如下: #include <iostream> using namespace std; int division(int x){ return x/2; } long division(long x){ re

  • c语言与c++基础知识点(必看)

    1.后缀名: C++/C程序的头文件以.h为后缀,C程序的源文件以.c为后缀,C++程序的源文件通常以.cpp为后缀(有些书中介绍有一些系统以.cc或.cxx为后缀的源文件). 在Linux系统下的gcc,.C(部分),.cc或.cxx 为后缀的源文件, 它们也是C++源代码文件. 2.extern关键字:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern有两个

  • c++运算符重载基础知识详解

    实际上,很多C++运算符已经被重载.eg:将*运算符用于地址,将得到存储在这个地址中的值,将他用于2个数字时,得到的将是他们的乘积.C++根据操作数的数目和类型来决定采用哪种操作. C++允许将运算符重载扩展到用户定义的类型.例如,允许使用+将两个对象相加.编译器将根据操作数的数目和类型决定使用加法定义.运算符重载可以使代码看起来更自然.例如,将2个数组相加是一种常见的运算.通常,需要使用下面这样的for循环来实现: 复制代码 代码如下: for (int i = 0; i < 20; i++)

  • C++基础入门教程(一):基础知识大杂烩

    我很郁闷,这本书果然讲得很详细,我在看第二章,看完要深呼吸,实在太详(lao)细(dao)了. 不过这很好,后面难一些的内容应该会不错~   那么,这章只是作为预览的章节,我抽出一些稍微比较有营养的内容记录一下吧~   注意:本系列教程不适合无任何编程语言基础的朋友,只是作为C++基础的一种补充. 教程内容基于<C++ Primer Plus>一书,适合初学者,熟手请直接忽略. 1. 如果你不注释,那么,我会把你注释掉~! C++的注释有2种, 第一种,单行注释,那就是:// 如下代码: 复制

  • AngularJS实用基础知识_入门必备篇(推荐)

    前言 今天来和大家学习一下AngularJS-- AngularJS 通过新的属性和表达式扩展了 HTML. AngularJS 可以构建一个单一页面应用程序. AngularJS 学习起来非常简单. 一.AngularJS指令与表达式 [AngularJS常用指令] 1.ng-app:声明Angular所管辖的区域,一般写在body或HTML上,原则上一个页面只有一个. 2.ng-model:把元素值(比如输入域的值)绑定到应用程序的变量中. eg:<input type="text&q

  • AngularJS 最常用的八种功能(基础知识)

    AngularJS 使用基础知识 第一 迭代输出之ng-repeat标签 ng-repeat让table ul ol等标签和js里的数组完美结合 <ul> <li ng-repeat="person in persons"> {{person.name}} is {{person.age}} years old. </li> </ul> 你甚至可以指定输出的顺序: <li ng-repeat="person in pers

  • PHP小白必须要知道的php基础知识(超实用)

    很多人看到PHP就以为是程序员,就以为钱很多(虽然是事实),但是也要考虑下自己是不是适合这一行,知道PHP是什么吗?PHP都有什么样的功能,都能用来干嘛? PHP是什么? •PHP(PHP: Hypertext Preprocessor,超文本预处理器的缩写),是一 种被广泛应用的开放源代码的.基于服务器端的用于产生动态网页 的.可嵌入HTML中的脚本程序语言,尤其适合 WEB 开发. •当客户端向服务器的程序提出请求时,web服务器根据请求晌应对应 的页面,当页面中含有php脚本时,服务器会交

  • ASP新手必备的基础知识

    我们都知道,ASP是Active Server Page的缩写,意为"动态服务器页面".ASP是微软公司开发的代替CGI脚本程序的一种应用,它可以与数据库和其它程序进行交互,是一种简单.方便的编程工具.下面介绍一些基本知识,供大家参考. 一.数据库连接 以下为引用的内容: <% set conn=server.createobject("adodb.connection") conn.open "driver={microsoft access dr

  • 学习shell脚本之前的基础知识[图文]

    日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考的项目.有的单位甚至用shell脚本的编写能力来衡量这个linux系统管理员的经验是否丰富.笔者讲这些的目的只有一个,那就是让你认真对待shell脚本,从一开始就要把基础知识掌握牢固,然后要不断的练习,只要你shell脚本写的好,相信你的linux求职路就会轻松的多.笔者在这一章中并不会多么详细的介绍shell脚本

  • HTTP报文及ajax基础知识

    HTTP报文 客户端传递给服务器的内容 和 服务器传递给客户端的内容 都属于HTTP报文 起始行:请求起始行  响应起始行 首部:请求首部 响应首部 通用首部(请求和响应都有的) 自定义首部 主体:请求主体  响应主体 客户端传递给服务器端数据: 请求URL后面问号传参的方式传递给服务器  /getList?name=zhangsan&age=7 设置请求的首部(设置请求头信息) 设置请求主体,把传递给服务器的内容放在请求主体中传递给服务器 服务器端传递给客户端数据: 设置响应头信息 设置响应主

  • Lua中函数与面向对象编程的基础知识整理

    函数 1. 基础知识 调用函数都需要写圆括号,即使没有参数,但有一种特殊例外:函数若只有一个参数且参数是字面字符串或table构造式,则圆括号可有可无,如dofile 'a.lua',f{x=10, y=20}. Lua为面向对象式的调用提供冒号操作符的特殊语法,如o.foo(o, x)等价于o:foo(x).和Javascript类似,调用函数时提供的实参数量可以与形参数量不同,若实参多了则舍弃,不足则多余的形参初始化为nil. 1.1 多重返回值 Lua允许函数返回多个结果,函数返回如ret

  • GO语言(golang)基础知识

    今天说一些golang的基础知识,还有你们学习会遇到的问题,先讲解hello word 复制代码 代码如下: package main import "fmt" func main() {    fmt.Println("你好,我们"); } package name 包机制,每一个独立的go程序都需要有一个package main的申明,主要是要为下边入口函数main()做申明的,import和java一样导入包用的 就是下边我们函数用的fmt.Println()

  • sql注入之必备的基础知识

    什么是SQL注入(SQL Injection) 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击. mysql常用注释 # --[空格]或者是--+ /*-*/ 在注意过程中,这些注释可能都需要进行urlencode. mysql认证绕过 ;%00 ' or 1=1 # ' /*!or */

  • JavaScript基础知识及常用方法总结

    JAVASCRIPT是AJAX技术中不可或缺的一部分,所以想学好AJAX以及现在流行的AJAX框架,学好JAVASCRIPT是最重要的. 一.基础知识: 1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4.一个浏览器窗口中的DOM顺序是:window->(navigator,screen,history,location,document) 5.得到表单

随机推荐