0%

函数指针

1
void func(int a,int b , int (*func2)(int x, int y));

函数指针function pointer通常应用于菜单驱动的系统中。系统提示用户从菜单中选择一种操作,每个选项的操作都是由不同过的函数来完成的。指向每个函数的指针就存储在一个指针数组中。用户的选择将作为数组的下标,并且数组中的指针被用于调用相应的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>

void function1(int a, int b);
void function2(int a, int b);
void function3(int a, int b);

int main(void)
{
void (*f[3])(int ,int) = {function1,function2,function3};
int choice;


printf("Enter a number between 0 and 2, 3 to end:");
scanf("%d",&choice);

while(choice >= 0 && choice < 3)
{
(*f[choice])(choice);
printf("Enter a number between 0 and 2, 3 to end:");
scanf("%d",&choice);
}

printf("Program execution completed.\n");
return 0;
}

void function1(int a, int b)
{
printf("You are now using function1");
}

void function2(int a, int b)
{
printf("You are now using function1");
}

void function3(int a, int b)
{
printf("You are now using function1");
}

函数形参为const

如果一个变量作为实参传递给一个函数,并且这个变量没有也不应该在这个函数体中被修改,那么应该将这个变量声明为const,以避免其被意外改写,比如:

1
extern char *strcpy(char dest[],const char *src);

这个函数我们可以保证src肯定不能被修改的。

const的含义

  • const char *p:p为指向字符常量的指针
  • char const *p:p为指向字符常量的指针
  • char * const p:声明一个指向字符的指针常量p

little-endian和big-endian区别

endian一词源于小说格列佛游记,小说中,小人国为水煮蛋从大的一段big-end还是小的一端little-end剥开而争论(我习惯从大端打开clip_image001),争论的双方分别被称为big-endians和little-endians。

对于字节序的典型情况为整数在内存中的存放方式和网络传输的传输顺序

  • 小端序:LSByte在MSByte的前面,即LSB为低地址,MSB为高地址;
  • 大端序:MSByte在LSByte的前面,即LSB为高地址,MSB为低地址;

对于单一的字节,大部分处理器以相同的顺序处理位元bit,因此单字节的存放方法和传输方式一般相同。

Linux 之 killall 命令

.. _linux-beginner-killall:

.. note::
及时当勉励,岁月不待人。
陶渊明《杂诗·人生无根蒂》

命令概述

在Linux系统中,有许多命令可用于进程管理和控制。

其中一个常用的命令是killall,它允许用户通过进程名字来终止运行中的进程。

官方定义为:

killall – kill processes by name

killall命令用于向操作系统发送信号以终止指定进程。与kill命令不同,killall根据进程名字而不是进程ID来选择要终止的进程。这对于同时终止多个同名进程非常有用。

超级管理员可以kill掉任何进程。

基本语法

killall命令的基本语法如下:

1
$ killall [选项] 进程名

可以使用以下选项对killall命令进行调整:

  • -i:交互式模式,要求用户确认终止每个进程。
  • -e:精确匹配进程名,不匹配进程名的任何子串。
  • -s:指定要发送的信号类型,如-s HUP
  • -v:显示详细的终止进程的输出。

使用示例

终止单个进程

要终止单个进程,可以使用以下命令:

1
$ killall 进程名

比如:

1
$ killall firefox

这将终止所有名为firefox的进程。

终止多个进程

要同时终止多个同名进程,可以使用以下命令:

1
$ killall -r 进程名

示例:

1
$ killall -r chrome

这将终止所有以chrome为名的进程,包括chromechromium等等。

交互式模式

使用-i选项可以在终止每个进程之前要求用户确认。示例:

1
$ killall -i firefox

在执行此命令时,系统将逐个显示要终止的进程,并要求用户确认是否继续,这个对于不确定是否一定中止的优点用哟。

指定信号类型

可以使用-s选项来指定要发送的信号类型。示例:

1
$ killall -s HUP nginx

这将向所有名为nginx的进程发送HUP信号,以重新加载配置。

综上

killall命令是一个强大的进程管理工具,可帮助用户终止指定名称的进程。它简化了终止多个同名进程的操作,并提供了一些有用的选项,如交互式模式和指定信号类型。在日常的系统管理和故障排除中,killall是一个重要的工具,

i++和++i的区别

i++:对i增加1,但返回的是原来的未增加的值;

++i:在i存储的值上增加1并向使用它的表达式“返回”新的、增加后的值;

Mark:在c++中应该优先使用++i。

基于Doxygen的C/C++注释原则

#define OST_TIMESTAMP DATE “ “ TIME

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

## 1. 文件头的标注

```c
/*****************************************************************************
* The ATAS Library *
* Copyright (C) 2010 Shaoguang Guo sgguo@shao.ac.cn *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 3 as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License *
* along with SHAO. If not, see <http://www.gnu.org/licenses/>. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
* @file Example.h *
* @brief brief introduction *
* Details. *
* *
* @author Shaoguang Guo *
* @email sgguo@shao.ac.cn *
* @version 0.1(version) *
* @date 2010.07.16 *
* @license GNU General Public License (GPL) *
* *
*----------------------------------------------------------------------------*
* Remark : Description *
*----------------------------------------------------------------------------*
* Change History : < can omit if using VCS > *
* <Date> | <Version> | <Author> | <Description> *
*----------------------------------------------------------------------------*
* 2010/07/16 | 0.1 | Shaoguang Guo | Init the repo *
*----------------------------------------------------------------------------*
* *
*****************************************************************************/

2.命名空间

1
2
3
4
5
6
7
/**
* @brief 命名空间的简单概述 \n(换行)
* 命名空间的详细概述
*/
namespace OST
{
}

3. 类、结构、枚举标注

1
2
3
4
5
6
7
/**
* @brief 类的简单概述 \n(换行)
* 类的详细概述
*/
class Example
{
};

枚举类型定义、结构体类型定义注释风格类似

1
2
3
4
5
6
7
8
9
/**
* @brief 简要说明文字
*/
typedef struct 结构体名字
{
成员1, /*!< 简要说明文字 */ or ///<说明, /**<说明 */ 如果不加<,则会认为是成员2的注释
成员2, /*!< 简要说明文字 */ or ///<说明, /**<说明 */
成员3, /*!< 简要说明文字 */ or ///<说明, /**<说明 */
}结构体别名;

4. 函数注释原则

1
2
3
4
5
6
7
8
9
/**
* @brief 函数简要说明-测试函数
* @param index 参数1
* @param t 参数2 @see CTest
*
* @return 返回说明
* -<em>false</em> fail
* -<em>true</em> succeed
*/
bool Test(int index, const CTest& t);

note:指定函数注意项事或重要的注解指令操作符
note格式如下:
        @note 简要说明

retval:指定函数返回值说明指令操作符。(注:更前面的return有点不同.这里是返回值说明)
retval格式如下:
        @retval 返回值 简要说明

pre:指定函数前置条件指令操作符
pre格式如下:
        @pre 简要说明

par:指定扩展性说明指令操作符讲。(它一般跟code、endcode一起使用 )
par格式如下:
      @par 扩展名字

code、endcode:指定
code、endcode格式如下:
        @code
            简要说明(内容)
        @endcode

see:指定参考信息。
see格式如下:
        @see 简要参考内容

deprecated:指定函数过时指令操作符。
deprecated格式如下:
      @deprecated 简要说明 

  调试Bug说明
    解决的bug说明,@bug
  警告说明 (warning)
    定义一些关于这个函数必须知道的事情,@warning
  备注说明 (remarks)
    定义一些关于这个函数的备注信息,@remarks
  将要完成的工作 (todo)
    说明哪些事情将在不久以后完成,@todo
  使用例子说明 (example)
    例子说明,@example example.cpp

5. 变量注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /// 简述
/** 详细描述. */
或者
//! 简述
//! 详细描述
//! 从这里开始
int m_variable_1; ///< 成员变量m_variable_1说明
int m_variable_2; ///< 成员变量m_variable_1说明

/**
* @brief 成员变量m_c简要说明
*
* 成员变量m_variable_3的详细说明,这里可以对变量进行
* 详细的说明和描述,具体方法和函数的标注是一样的
*/
bool m_variable_3;

如果变量需要详细说明的可已按照m_varibale_3的写法写,注意,m_variable_2和m_variable_3之间一定需要空行,否则会导致m_variable_2的简述消失

6. 模块标注

模块定义格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @defgroup 模块名 页的标题名 (模块名只能英文,这个可以随便取.在一个源文件里不能相同)
* @{ (跟c语言{一样起作用域功能)
*/
… 定义的内容 …
/** @} */

例:
/**
* @defgroup HenryWen Example.cpp
* @{
*/
… 定义的内容 …
/** @} */

7. 分组标注

分组定义格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @name 分组说明文字
* @{
*/
… 定义的内容 …
/** @} */

例:
/**
* @name PI常量
* @{
*/
#define PI 3.1415926737
/** @} */

/**
* @name 数组固定长度常量
* @{
*/
const int g_ARRAY_MAX = 1024;
/** @} */

sizeof和strlen的区别

sizeof函数返回的是变量声明后所占的内存数,不是实际长度;

sizeof是一个编译时执行的运算符,所以它不会导致额外的运行时开销。

strlen函数求的是字符串的实际长度;