http://blog.csdn.net/hnhbdss/article/details/2470959
blog.csdn.net/hnhbdss/article/details/2470959
1.shell调试
(1).使用sh 选项调试
-n 只读取shell脚本,但是不执行;可以用来判断shell脚本是否有语法错误
-x 可以用来跟踪脚本的执行,会打印出每行命令的具体执行命令。特别要注意的是 -x 是把打印的结果存在标准错误输出中。
还要注意的是,我们在执行 -x 时会发现行首会有一个"+"(加号)。这个加号是由 SP4 这个环境变量来设置的。
为了调试的方便,我们可以修改SP4的值让它方便我们调试:
比如: export SP4='+{$LINENO:{$FUNCNAME[0]}}'
其中 LINENO 是shell内置环境变量,表示行号
FUNCNAME也是shell内置环境变量,其中FUNCNAME[0]表示当前代码所在的函数名;FUNCNAME[1]表示调用函数这个函数的函数名,以此类推
sh -x ./tem.sh 0>a0.txt 1>a1.txt 2>a2.txt
0表示标准输入 使用 < 或者 <<
1表示标准输出 使用 > 或者 >>
2表示标准错误 使用 > 或者 >>, -x就输出到这里
2.shell脚本
summarize:
1.重要的关键字
(1).mutable
mutable和const成员函数配对使用。当一个变量被声明为mutable后,即使在const成员函数里面,也能改变这个变量的值。
mutable只能用于类的非静态和非常量数据成员。
ex:
class A
{
void inc() const;
mutable int m_a;
};
void A::inc() const
{
m_a++;
}
(2).volatile
volatile告诉编译器不要持有该变量的临时拷贝,每次都到内存里面从新取值。使用临时变量的情况主要是在代码优化的时候会使用。
volatile可以用于基础类型(int,char,long等),也可以用于类和结构体类型。
ex:
void f(volatile int *p);
volatile int *p;
(3).explicit
explicit关键字的作用是,禁止“单参构造函数”被用于自动类型转换。
ex:
explicit 主要是禁止下面的转换。
class A
{
public:
explicit A(int a);
};
A a;
a = 1;//有了explicit关键字后这里编译将报错。
2.双检锁(double-check lock)
双检锁被使用于很多资源有延迟加载的情况。
下面以单工模式做为例子。
单工模式使用双检锁的好处是:能减少对 mutex 的进入,提高效率。
ex:
//传统的单工模式
class singleA
{
singleA * getIns()
{
mutex_lock();
if ( m_p == NULL )
{
m_p = new singleA;
}
mutex_unlock();
return m_p;
}
};
//双检锁的单工模式
class singleA
{
singleA * getIns()
{
if ( m_p == NULL )
{
mutex_lock();
if (m_p == NULL )
{
m_p = new singleA;
}
mutex_unlock();
}
return m_p;
}
};
3.临时变量导致析构函数被调用两次
class stack
{
public:
stack(const char *value);
~stack();
char * data;
};
stack::stack(const char *value)
{
if(value)
{
data = new char[strlen(value)+1];
strcpy(data,value);
}
else21. {
data = new char[1];
*data = '/0';
}
}
inline stack::~stack()
{
cout << "Destructor" << endl;
//delete []data; //此处会报错 31.}
void dosth(stack pstk)
{
cout << pstk.data << endl;
}
int main()
{
stack str("iamxczhang");
dosth(str);
return 0;
}
错误的原因:dosth导致一个临时变量被创建,所以析构函数会被调用两次。所以这里一个深拷贝和浅拷贝的问题。
解决方法: 重载拷贝构造函数可以解决问题。
字符串指针和数组
(1).
char *pStr ="abc";
char str[] = "abc";
pStr[0] = '0';//这里会报错,因为这里的指针指向的是常量区的字符串
str[0] = '0';//这里编译器不会报错,因为这里会为数组在栈里面分配存放"abc"的内存
sizeof(str) = sizeof("abc") = 4
strlen(str) = 3
(2);
char *p[2]={"aaa","sdfsds"};
注意这里的字符串"aaa",和"sdfsds"也是存放在只读区。因为p是指向字符串的指针。
即使这里没有使用const定义p(const char* p[]..),编译也是能通过的