`

C语言 命令行参数 函数指针 gdb调试

 
阅读更多

.


作者:万境绝尘

转载请注明出处:http://blog.csdn.net/shulianghan/article/details/21551397|http://www.hanshuliang.com/?post=29


.



1. C语言命令行参数详解


命令行参数 : 有两个参数 int argc 和 char **argv;

-- argc : 标示输入的参数个数, 注意命令本身也是参数;

-- argv : 指向 字符串数组的指针, 每个字符串是一个参数;

-- 约定 : argv[0] 是 程序名称, argc 的最小值是1, 如果argc 是1, 那么说明 命令后面没有参数;


(1) 模仿 echo 程序 示例


echo程序示例 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ echo csdn
csdn
octopus@octopus-Vostro-270s:~/code/c/pointer$ echo Hello World
Hello World
-- 分析命令行 : echo Hello World 将 Hello World 输出到命令行中, 该命令 argc 值是3, argv[0] 是 echo, argv[1] 是 Hello, argv[2] 是 World, 注意 argv[3] 是 空指针 0;


使用数组下标方式访问参数模仿echo示例程序 :

/*************************************************************************
    > File Name: echo.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月19日 星期三 19时56分36秒
 ************************************************************************/

#include<stdio.h>

int main(int argc, char **argv)
{
	int i;
	for(i = 1; i < argc; i ++)
	{
		//将参数输出, 每次注意输出一个空格, 如果是最后一个那就不用输出空格了
		printf("%s%s", argv[i], (i < argc - 1) ? " " : "");
	}
	printf("\n");
	return 0;
}


执行效果 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ ./echo Hello World
Hello World


使用指针访问参数模仿echo程序 :

/*************************************************************************
    > File Name: echo_pointer.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月19日 星期三 20时08分07秒
 ************************************************************************/

#include<stdio.h>

/*
 * echo Hello World
 * 循环条件 : --argc, 如果参数只有一个 echo 那么什么都不用打印
 * 打印参数个数 : 如果参数有 3 个, 那就循环 2 次, 打印两个参数
 * 打印参数 : 从 第 2 个参数开始打印
 * 打印空格 : 如果argc > 1, 说明下一轮还要继续打印, 此时打印空格
 */
int main(int argc, char **argv)
{
	while(--argc > 0)
		printf("%s%s", *++argv, (argc > 1) ? " " : "");
	printf("\n");
	return 0;
}

执行结果 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc echo_pointer.c -o echo
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./echo Hello World
Hello World




(2) 模仿 简单grep 程序



程序介绍 : 模仿 grep 过滤, 过滤数据来自标准输入流, grep 命令匹配第一个参数, 凡是输入的字符串 包含 第一个参数字符串, 就输出这个字符串, 相当于将字符串输出了2遍;


代码 :

/*************************************************************************
    > File Name: grep.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月19日 星期三 20时45分47秒
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#define MAXLEN 50

//先声明函数, 才能在main函数中使用, 否则函数要在main函数之前定义才可以使用
int get_line(char *line, int max);

int main(int argc, char **argv)
{
	char line[MAXLEN];
	int found = 0;
	if(argc == 1)
		printf("wrong parameters ! \n");
	else
		/*
		 * 当获取的字符个数大于1的时候
		 * 比较字符串 与 参数1
		 * 如果返回的不为NULL, 那么说明查找到了字串
		 * 将字串打印出来
		 */
		while(get_line(line, MAXLEN) > 0)
		{
			if(strstr(line, argv[1]) != NULL)
			{
				printf("%s \n", line);
				found ++;
			}
		}
	return 0;
}

/*
 * 从标准输入流中获取字符串, 将字符串存储到 char *line 指针指向的数组中
 * 注意字符串最大为50个, 字符最多有49个, 剩下的最后一位存放 '\0'
 * 从标准输入流中读取字符, 放到数组中
 * 停止读取字符条件 : 个数到达 48个, 读取到了 回车 '\n' 或者 EOF (ctrl + D)
 */
int get_line(char *line, int max)
{
	int i, c;
	for(i = 0; (c = getchar()) != '\n' && c != EOF && i < max - 1; i++)
		line[i] = c;
	line[i] = '\0';
	return i;
}

执行结果 : 参数是 abc, 如果输入的字符串包含 abc, 那么就将字符串再输出一遍;

octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc grep.c -o grep
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./grep abc
qwe
asd
zxc
qabc
qabc 
wabcc
wabcc 
12


要点解析 :

-- int get_line(char *line, int max)函数 : 从输入流中获取输入, 当获取到'\n'或者EOF的时候, 就会返回该字符串指针, 注意 函数如果命名为 getline()就会报错, 与库函数同名了;

-- char *strstr(const char *haystack, const char *needle)函数 : 查询 haystack字符串中 是否包含 needle 字符串, 如果包含, 就将查询到的子字符串的指针返回;



(3) 模仿带可选参数的grep程序



需求 : 给程序加上可选参数;

-- UNIX程序约定 : 命令中 负号开头的参数是可选的参数, 例如 ls -la, ls 是将目录中的文件列出, 后面的 -la 可有可无;

-- 模拟grep程序可选参数 : -x 代表打印不匹配的文本行, -n 打印行号, 可以使用 grep -x -n 格式, 也可以使用 grep -nx 格式;


要点解析 :

-- option_analysis参数 : 因为在后面需要用到 输入的过滤参数, 即argv 的非 可选参数, 在遍历可选参数的时候, 会对argv进行一系列的自增操作, 如果我们传入的是argv二级指针, 那么在函数中进行的自增操作不会改变argv值, 这里我们需要改变argv的值, 因此需要传入 argv二级指针的地址, 三级指针;

-- 区分 (*++argv)[0] 和 *++argv[0] : []的优先级最高, 下面的框图分析两种情况 , 先进行 (*++argv)[0], 然后进行 *++argv[0]运算;


(*++argv)[0] 与 *++argv[0]图解 :

-- argv参数 :


-- 执行(*++argv)[0]表达式 :


-- 执行*++argv[0]表达式 :




代码 :

/*************************************************************************
    > File Name: grep_option.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月21日 星期五 09时30分07秒
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#define MAXLEN 15

char line[MAXLEN];
int c, lineno = 0, except = 0, number = 0, found = 0;

int get_line(char *line, int max);
void option_analysis(int argc, char ***argv);
void out_put(char **argv);

int main(int argc, char **argv)
{

	option_analysis(argc, &argv);
	out_put(argv);
	return 0;
}

/*
 * 从标准输入流中获取字符串, 最长能获取max个
 * 个数计算 : 
 *	 字符串最长是 max 个
 *	 注意里面包含了 '\0' 
 *	 实际字符个数只能是 max - 1 个
 *	 实际的最大下标是 max - 1
 * 字符串终止 : 
 *   输入 '\n' (回车)
 *   输入 EOF (CTRL + D)
 *   字符个数达到 max - 1 个
 * 注意 : 最后一个元素赋值为 '\0'
 */
int get_line(char *line, int max)
{
	int i, c;
	for (i = 0; (c = getchar()) != '\n' && c != EOF && i < max - 1; i++)
	{
		line[i] = c;
	}
	line[i] = '\0';
	return i;
}

/*
 * 分析可选参数情况, 根据接收到的可选参数情况, 设置标识位
 *
 * 后来对方法参数进行了小修改, 这里需要改变argv指针指向, 
 * 因此需要将该指针的地址传给函数
 *
 * 区分 (*++argv)[0] 和 *++argv[0]
 *   (*++argv)[0] : 
 *     执行顺序 : (*(++argv))[0], * 和 ++ 同时存在 执行顺序自右向左
 *     执行效果 : 
 *       ++argv 将指针指向了 下标为1 的字符串首地址 
 *       *++argv 指的是第一个字符串
 *       (*++argv)[0] 获取的是第一个字符串的第0个字符元素, 这里用来判断是不是'-'
 *   *++argv[0] : 此时argv指向第二个字符串首地址
 *     执行顺序 : *(++(argv[0])) 
 *     执行效果 : 
 *       取出第0个字符串的第1个字符, 该串的第0个字符是'-'
 *       argv[0]得到第0个字符的指针
 *       ++argv[0] 是该字符串的第二个元素的地址
 *       *++argv[0] 是该字符串第二个元素
 */
void option_analysis(int argc, char ***argvp)
{
	/*
	 * 根据--argc > 0 判断输入的参数, 如果 --argc 大于0, 那么说明后面还有参数 
	 * 循环所有的参数, 将所有的 -可选参数遍历出来
	 *
	 * 每次循环 argv 指针就自增, 指向下一个参数字符串
	 * 如果字符串的第0个字符是 '-',  那么该参数字符串是可选参数
	 */
	while (--argc > 0 && (*++(*argvp))[0] == '-')
	{
		/*
		 * 先获取这个可选字符串指针, 然后在一次遍历这个指针
		 * 根据遍历的结果设置对应的标识位
		 */
		while (c = *++(*argvp)[0])
		{
			switch(c)
			{
				case 'x':
					except = 1;
					break;
				case 'n':
					number = 1;
					break;
				default:
					printf("option illegal \n");
					argc = 0;
					found = -1;
					break;
			}
		}
	}
}

/*
 * 在上面的option_analysis函数中传入的argv指针的地址, 因此上面对argv的自增操作改变了指针
 * 这里的*argv 就可以取出 argv 第0个元素字符串的指针
 *
 * 如果输入的字符串能匹配参数
 *   没有输入x的情况
 *     输入了n 输出带行号, 不匹配的字符串
 *     没有输入n 输出不带行号, 不匹配的字符串
 *   如果输入了x参数
 *     输入了n 输出带行号的, 匹配的字符串
 *     没有输入n , 输出不带行号的, 匹配的字符串
 */
void out_put(char **argv)
{
	while (get_line(line, MAXLEN) > 0)
	{
		lineno++;
		if ((strstr (line, *argv) != NULL) != except)
		{
			if(number)
				printf("%d : ", lineno);
			printf("%s \n", line);
		}
	}
}

执行结果 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc grep_option.c -o grep
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./grep -xn a
qw
1 : qw 
as
qc
3 : qc 
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./grep -n a
qw
as
2 : as 
qc
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./grep -x a
qw
qw 
as
qc
qc 



2. 函数指针 和 指针函数



(1) 指针函数


概念 : 函数返回的结果是一个地址, 即返回的是一个指针, 这个函数就是指针函数;


指针函数格式 : 类型说明符 *函数名(参数列表);

-- 示例 : char *getchar(void);

-- 格式说明 : char * 表示函数返回值是指针, 调用这个函数, 返回一个指针指向的char类型;


运算符优先级 : 指针函数有两个运算符 * 和 (), ()的优先级 大于 *, 因此函数名首先和 () 结合, 然后在和 * 结合;



(2) 函数指针


概念 : 函数指针指向了函数的地址, 该指针可以调用函数;

函数指针格式 : 类型说明符 (*指针名)(参数列表);

-- 示例 : char (*getcahr)(void);


运算符优先级 : * 和 指针名 先结合, 然后在与参数列表结合;


函数指针使用 :

-- 声明函数指针 : void (*getchar)(), 声明函数指针需要带上参数列表;

-- 为函数指针赋值 : getchar = &get_char 或者 getchar = get_char 两种方法, & 可有可无;

-- 调用函数指针方法 : (*get_char)();



(3) 使用函数指针示例


示例需求 :

-- 获取字符串数组 : 从标准输入流中读取字符串数据, 将字符串放入字符串数组 char **;

-- 可选参数 : -n, 如果有可选参数, 就是按照数值顺序排序, 否则按照字典顺序排序;


代码 :

/*************************************************************************
    > File Name: method_pointer_sort.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: Sat 22 Mar 2014 11:45:47 PM CST
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//定义排序字符串最大个数
#define MAXLINES 50
//每个字符串最多50个元素
#define MAXLEN 50
//定义一个 有MAXLINES 个 元素的数组, 数组中的元素师字符串, 即char类型指针
char *lineptr[MAXLINES];

/*
 * 声明函数指针
 */
int (*p_get_line)(char *, int);
int (*p_read_lines)(char **, int);
void (*p_write_lines)(char **, int);
void (*p_q_sort)(void **, int, int, int (*)(void *, void*));

/*
 * 声明函数, 如果直接使用这些函数, 即使函数定义在主函数后面也不会出错
 * 如果要将函数赋值给函数指针, 需要提前声明这些函数
 */
int get_line(char *, int);
int read_lines(char **, int);
void write_lines(char **, int);
void q_sort(void *v[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);

int main(int argc, char **argv)
{
        char line[MAXLEN];
        int len, nlines, numberic = 0;

        p_read_lines = read_lines;

        p_write_lines = write_lines;

        p_q_sort = q_sort;

        //如果参数中含有 -n 说明这是按照数值顺序排序, 否则就按照字典顺序排序
        if(argc > 1 && strcmp(argv[1], "-n") == 0)
                numberic = 1;

        if((nlines = (*p_read_lines)(lineptr, MAXLINES)) >= 0)
        {
                /*
                 * 注意 : 
                 *   使用 ? : 表达式选择 函数指针, 函数指针类型转换的时候, 为每个选项都添加转换
                 *   如果只转换 ? : 结果, 会报出警告
                 */
                (*p_q_sort)((void **)lineptr, 0, nlines - 1, numberic ? (int (*)(void*, void*))numcmp : (int (*)(void*, void*))strcmp);
                (*p_write_lines)(lineptr, nlines);
                return 0;
        }
        else
        {
                printf("error \n");
                return 1;
        }

}

//从标准输入流中读取数据, 放入字符串中
int get_line(char *line, int max)
{
        int i, c;
        for(i = 0; (c = getchar()) != '\n' && c != EOF && i < max - 1; i ++)
        {
                *(line + i) = c;
        }
        *(line + i) = '\0';
        return i;
}

//从标准输入流中读取数据, 放入字符串数组
int read_lines(char *lineptr[], int max)
{
        int len, nlines = 0;
        char *p, line[MAXLEN];

        while((len = get_line(line, MAXLEN)) > 0)
        {
                if(nlines >= MAXLINES || (p = malloc(sizeof(char) * (len + 1))) == NULL)
                {
                        return -1;
                }
                else
                {
                        strcpy(p, line);
                        *(lineptr + nlines) = p;
                        nlines++;
                }
        }
        return nlines;
}

//将字符串数组中的元素打印出来
void write_lines(char *lineptr[], int nlines)
{
        int i;
        for(i = 0; i < nlines; i++)
        {
                printf("the %d char sequence is : %s \n", i, *(lineptr + i));
        }
}

//数值比较
int numcmp(char *s1, char *s2)
{
        double v1, v2;

        v1 = atof(s1);
        v2 = atof(s2);

        if(v1 < v2)
                return -1;
        else if(v1 > v2)
                return 1;
        else if(v1 == v2)
                return 0;
}

//交换数组中 i j 元素
void swap(void *v[], int i, int j)
{
        void *temp;

        temp = *(v + i);
        *(v + i) = *(v + j);
        *(v + j) = temp;
}

//排序方法
void q_sort(void *v[], int left, int right, int (*comp)(void *, void *))
{
        int i, last;

        if(left >= right)
        {
                return;
        }
        swap(v, left, (left + right)/2);
        last = left;
        for(i = last + 1; i <= right; i++)
        {
                if((*comp)(v[i], v[left]) < 0)
                        swap(v, ++last, i);
        }
        swap(v, left, last);
        q_sort(v, left, last - 1, comp);
        q_sort(v, last + 1, right, comp);

}


执行结果 :

[root@ip28 pointer]# gcc method_pointer_sort.c 
[root@ip28 pointer]# ./a.out 
qwe
asd
zxc
rty

the 0 char sequence is : asd 
the 1 char sequence is : qwe 
the 2 char sequence is : rty 
the 3 char sequence is : zxc 
[root@ip28 pointer]# ./a.out -n
qwe
asd
zxc
rty

the 0 char sequence is : asd 
the 1 char sequence is : zxc 
the 2 char sequence is : qwe 
the 3 char sequence is : rty 


.

3. 指针函数的复杂案例分析


(1) 指针函数 和 函数指针 分析


示例 :

-- 示例一 :char *get_line(char *line, int max);

-- 示例二 : char **get_line(char *line, int max);

-- 示例三 : int *(*get_line)(char *line, int max);


分析 :

-- 示例一 : get_line 普通函数, 返回值是一个char类型指针, 即返回一个字符串;

-- 示例二 : get_line 普通函数, 返回值是一个二级指针, 即字符串数组;

-- 示例三 : get_line 函数指针, 该指针的返回值是一个int类型的指针, 即指针; get_line不是函数名, 是一个指针变量, 使用 int *(*)(char *line, int max) get_line 可以清楚的定义该指针, 不过如果这样定义就错误了;


(2) 指函数指针转换


示例 :

char fun();
void (*p)();
*(char*)&p = (char)fun;
(*p)();


解析 :

-- void (*p)() : 该表达式定义了一个函数指针, 该指针p 指向一个函数, 这个函数的返回值 和 参数都为NULL;

-- *(char*)&p : p是函数指针, &p 是指向函数指针的指针, (char*)&p 将 指向函数指针的指针 类型改为 char*, *(char)&p 就是 取出转换类型的函数指针, 这个是已经转换好类型的函数指针;

-- (char)fun : 将fun函数的 函数指针转换为 char 类型, 函数的入口地址转换为 char 类型;

-- *(char*)&p = (char)fun : 指的是将函数的地址 赋值给 指针变量p;

-- (*p)() : 调用这个 指针 指向的函数;


(3) 将地址转换成函数指针


示例 :

(*(void(*)())0)() ;


解析 :

-- void(*)() : 函数指针类型, 该类型指向的函数 返回值 和 参数 均为 NULL;

-- (void(*)())0 : 将 0 转换为函数指针, 前提是这个位置有该类型的函数;

-- *(void(*)())0 : 将 函数指针 指向的函数取出, 后面加上(), 就是执行这个函数;


(4) 函数指针作为返回值


示例 : 函数指针作为返回值, 正向写写不出来, 要反向推理;

char(*get_char(char))(char *, int);



分析 : 从get_char 开始解析;

-- get_char(char) : get_char 先跟()结合, 表明这是一个函数;

-- *get_char(char) : get_char(char) 与 * 结合, 表明该函数返回值是一个指针;

-- (*get_char(char))(char *, int) : (*get_char(char)) 返回指针, 与后面的(char *, int)结合, 返回的是一个函数指针, 该指针指向函数;

-- char(*get_char(char))(char*, int) : 表明这个返回值函数指针指向的函数的返回值是 char 类型;


简单的替代方法 : 使用 typedef;

typedef char(*RETURN)(char *, int);
RETURN get_char(char);
-- 解析 : 先定义一个 char(*)(char *, int) 类型的函数指针, 将该类型命名为 RETURN, 然后将其设置为 get_char(char) 函数的返回值;


(5) 函数指针数组


示例 : int (*get_char[2])(char *line, int max);


解析 : 定义了一个函数指针数组, 该数组中有两个函数指针元素, 这两个函数的返回值是 int, 参数列表是 char * 和 int;



4. 复杂声明


C语言声明运算符优先级 : C语言中, * 运算符的优先级低于 ();


char (*array)[13] 解析: 声明一个指针;

-- *array : 代表 array 定义的是一个指针;

-- (*array)[13] : (*array) 与后面的 [] 结合, 说明这个指针指向一个 数组;

-- char (*array)[13] : 说明数组中的元素类型是 char ;


char *array[13] 解析 : 声明一个数组;

-- array[13] : 声明一个数组, 这个数组中有13个元素;

-- *array[13] : 这个数组中的元素是指针类型元素;

-- char *array[13] : 指针类型为 char;


char *fun() 解析 : 声明指针函数;

-- fun() : fun 先与 () 结合, 说明 fun 是一个函数;

-- *fun() : fun() 与 * 结合, 说明返回值是 指针;

-- char *fun() : 返回的指针类型是 char 指针;


char (*fun)() 解析 : 声明一个函数指针;

-- *fun : 代表 fun 指向一个指针;

-- (*fun)() : 代表该指针指向一个函数;

-- char (*fun)() : 代表这个函数的返回值是一个 char 类型;


char (*(*fun())[])() 解析 : 声明一个函数;

-- fun() : fun 与 () 结合 说明这是一个函数;

-- *fun() : 说明 该 函数返回值是一个指针p1;

-- (*fun())[] : 该指针p1 指向一个数组array1;

-- *(*fun())[] : array1 数组 与 * 结合, 说明数组元素是 指针 p2;

-- (*(*fun())[])() : 指针 p2 与 () 结合, 说明该指针指向一个函数 fun;

-- char (*(*fun())[])() : fun 函数返回值是一个 char 类型;


char (*(*array[3])())[5] 解析 : 声明一个数组;

-- array[3] : 说明 声明的 array 是一个数组;

-- *array[3] : 表明 该数组元素类型是一个指针p1;

-- (*array[3])() : p1 指向的是一个函数, 即这是函数指针;

-- *(*array[3])() : 函数指针指向的函数返回值是一个 指针 *;

--(*(*array[3])())[5] : 表明该 指针 指向一个数组;

--char (*(*array[3])())[5] : 数组中的元素是 char 类型;


5. 使用gdb调试程序


简单使用gdb : 调试 上面 2.(3) 示例程序;

-- 编译可调试执行文件 : gcc -g method_pointer_sort.c ;

-- 使用gdb运行 : gdb a.out ;

-- 打断点 : break 53 , break 行号 可以给程序打断点;

-- 执行 : run , 使用该命令可以执行程序, 程序会在断点处停下来;

-- 查看变量 : printf 变量名 , 可以查看变量内容;

-- 继续执行 : n , 继续执行;


示例 :

[root@ip28 pointer]# gcc -g method_pointer_sort.c #编译可调试程序
[root@ip28 pointer]# gdb a.out #使用gdb执行调试
GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/code/pointer/a.out...done.
(gdb) list #列出程序内容
31      int get_line(char *, int);
32      int read_lines(char **, int);
33      void write_lines(char **, int);
34      void q_sort(void *v[], int left, int right, int (*comp)(void *, void *));
35      int numcmp(char *, char *);
36
37      int main(int argc, char **argv)
38      {
39              char line[MAXLEN];
40              int len, nlines, numberic = 0;
(gdb) break 53 #给53行打断点
Breakpoint 1 at 0x4006f9: file method_pointer_sort.c, line 53.
(gdb) run # 执行程序
Starting program: /root/code/pointer/a.out 
q
w
e
r


Breakpoint 1, main (argc=1, argv=0x7fffffffe988) at method_pointer_sort.c:59
59                      (*p_q_sort)((void **)lineptr, 0, nlines - 1, numberic ? (int (*)(void*, void*))numcmp : (int (*)(void*, void*))strcmp);
(gdb) print lineptr # 打印二维数组内容
$1 = {0x602010 "q", 0x602030 "w", 0x602050 "e", 0x602070 "r", 0x0 <repeats 46 times>}
(gdb) print nlines # 打印int类型变量
$2 = 4
(gdb) n # 继续执行
60                      (*p_write_lines)(lineptr, nlines);
(gdb) n #继续执行
the 0 char sequence is : e 
the 1 char sequence is : q 
the 2 char sequence is : r 
the 3 char sequence is : w 
61                      return 0;
(gdb) n
69      }
(gdb) n
0x000000306801d994 in __libc_start_main () from /lib64/libc.so.6
(gdb) quit #退出调试
A debugging session is active.

        Inferior 1 [process 7799] will be killed.

Quit anyway? (y or n) y


作者 : 万境绝尘

转载请注明出处 :http://blog.csdn.net/shulianghan/article/details/21551397|http://www.hanshuliang.com/?post=29


.

分享到:
评论

相关推荐

    GDB中应该知道的几个调试方法.txt

    因此,在使用GDB调试包含宏的代码时,需要注意以下几点: - **查看宏定义**:使用`info macros`命令可以查看宏定义及其展开情况。 - **宏定义的查看**:如果需要查看某个特定宏的定义,可以通过`info macro &lt;宏名&gt;`...

    C语言中pointers to pointers数据结构的使用201605

    通过简单的GDB的使用,来考察 1、考察C语言的main函数的参数列表*argv[]的特性。 2、考察C语言的二级指针的使用。(pointers arrays;pointers to pointers)

    C语言功能接口库

    例如,`main()`函数中的`argc`和`argv`参数就是用来处理命令行参数的。一个良好的命令行解析库可以帮助我们处理复杂的命令选项和参数,提高程序的可配置性和灵活性。 其次,**内存管理**是C语言程序设计的关键部分...

    C语言精彩教案-最新版

    - 主函数main():深入理解C程序的入口点,学习如何处理命令行参数。 3. **指针** - 指针的概念:介绍指针变量及其作用,理解指针与地址的关系。 - 指针操作:学习指针的声明、初始化、赋值和解引用,以及指针...

    C语言实训项目-查字典

    13. C 语言程序的命令行参数:命令行参数是指程序启动时传递给程序的参数。 14. 多文件符号解析:多文件符号解析是指将多个文件组合成一个可执行文件的过程。 15. 头文件包含:头文件是指包含函数声明和变量定义的...

    C语言精品课程网.zip

    - 函数指针:了解函数指针的使用,包括如何声明、赋值和调用函数指针,以及其在回调函数和动态内存分配中的应用。 - 内联函数和递归函数:探讨内联函数提高效率的方式,以及递归函数的原理和使用场景。 3. **数组...

    C语言课后答案超详细!

    - 主函数main():所有C程序的执行起点,理解其返回值和命令行参数的处理。 3. **指针** - 指针的概念:指针是C语言的一大特色,它存储内存地址,允许直接操作内存。掌握指针的声明、赋值和解引用是进阶学习的必备...

    Linux C语言手册.rar

    - 主函数main():程序执行的起点,通常用于接收命令行参数。 3. **指针** - 指针变量:存储内存地址的特殊变量,通过指针可以间接访问和修改其他变量。 - 指针操作:取地址符(&)、解引用(*),以及指针算术运算。...

    linux下C语言实现的电子词典

    5. **命令行参数处理**:在Linux环境下,程序通常通过命令行参数接收输入。需要了解`main`函数的`argc`和`argv`参数,以及`getopt`函数来解析这些参数,例如,用户可能通过命令行指定词典文件路径。 6. **用户交互*...

    自考C语言实践课实现

    9. **错误调试**:学会使用调试工具,如GDB,进行程序调试,找出并修复程序中的错误。 10. **编译与链接**:理解编译器的工作原理,学习如何编译和链接C程序,包括命令行选项和编译过程。 通过这些知识点的学习和...

    二级c语言上机试题 二级c语言上机试题

    5. 主函数main():主函数是程序的入口点,理解其特殊性及如何接收命令行参数。 6. 函数间的相互调用:理解局部变量和全局变量的区别,以及如何在函数间共享数据。 三、数组与指针 7. 一维数组与二维数组:掌握...

    C语言课程设计案例精编

    - 调试技巧:了解GDB等调试工具的使用,以及如何通过调试找出并修复程序错误。 7. **课程设计实例** - 图形界面程序:如使用C语言实现简单的命令行界面或图形界面应用。 - 数据结构实现:如链表、队列、栈、树等...

    Linux操作系统下C语言编程入门

    4. GDB调试器:GDB是Linux下的强大调试工具,可以帮助开发者查找和修复代码中的错误。 四、C语言编程基础 1. 数据类型:包括整型、浮点型、字符型等,理解和掌握它们的存储大小和使用场景至关重要。 2. 变量与常量...

    物资管理系统 C语言

    9. **函数指针**:在更高级的设计中,可能会用到函数指针,作为参数传递给其他函数,实现动态绑定或回调机制,增强系统的灵活性。 10. **编译与调试**:由于本系统在winTC下调试,理解编译器选项和调试工具的使用是...

    C语言编程工具

    同时,熟悉每个工具的特定功能和用法也是必要的,比如Dev-Cpp中的项目设置、lccwin32/lccwin64的命令行参数等。 在调试方面,IDE如Dev-Cpp通常内置了调试器,允许用户设置断点、单步执行代码、查看变量值,以便找出...

    linux环境C语言编程入门

    8. **调试技巧**:掌握GDB调试器的使用,学会设置断点、单步执行、查看变量值以及分析内存泄漏等问题。 9. **实践项目**:可能包含一些简单的实际项目,如创建简单的命令行工具,或实现特定的文件操作,以巩固理论...

    Linux下C语言2048游戏代码

    4. **命令行参数**:在Linux环境中,程序可能需要接收命令行参数来控制游戏行为。例如,用户可能希望指定游戏的大小或初始数字。学会使用`argc`和`argv`处理这些参数是必要的。 5. **内存管理**:C语言没有自动的...

    C语言程序900例

    - 主函数main():它是程序的入口点,通常用于接收命令行参数和执行程序主体。 - 自定义函数:创建自己的函数,实现特定功能,提高代码复用性。 3. **指针** - 指针的概念:理解指针存储的是内存地址,以及如何...

    毕业设计作品_C语言趣味程序百例精解.rar

    - 主函数main():程序执行的起点,通常用于接收命令行参数和初始化。 - 内联函数与递归函数:内联函数可以提高效率,而递归则是一种自调用的函数设计方式。 3. **指针**: - 指针的概念:存储内存地址的数据类型...

    C语言课程设计英语词典排版系统.zip

    - **命令行参数**:程序可能接受命令行参数,如输入文件路径和输出格式选项。 - **标准输入输出**:通过scanf/printf处理用户输入和显示结果。 5. **错误处理**: - **文件不存在**:处理打开文件失败的情况,...

Global site tag (gtag.js) - Google Analytics