LinuxC高级-2

【1】函数

1.定义:

函数是一个完成特定功能的代码模块,其程序代码独立。

2.格式:

(存储类型) 数据类型 函数名(形式参数)
{
	函数体;
	return 常量、变量或表达式;
}

int add(int a, int b)
{
        return a + b;
}

3.调用:

函数名(实参);

4.声明:

数据类型 函数名(形式参数);

int add(int a, int b);

int add(int, int);

5.函数的传参:

1)值传递:只是将值进行传递,对传递的值不会产生影响(复制传递)。

2)地址传递:将地址进行传递,在子函数中改变地址中的内容时,会对主函数的变量的值产生影响。

3)数组传递:int array(int a[], int n)

        进行数组传递时,并没有将整个数组进行传递,而是传递的是数组的首地址。

【2】指针函数

1.本质:

函数,函数的返回值为指针(地址)

2.格式:

数据类型 *函数名(参数)
{
return 地址;//return NULL;
}

代码示例(如下):
#include <stdio.h>
int add(int, int);
int main(int argc, char const *argv[])
{
    // int (*p)(int, int) = add;
    int (*p)(int, int) = NULL;
    p = add;
    printf("%d\n", add(3, 4));
    printf("%d\n", p(5, 6));
    return 0;
}

int add(int a, int b)
{
    return a + b;
}




// 7
// 11

【3】函数指针:

1.本质:

指针,指向函数的指针

char st[] = "hello";

char *p = st;

用指针(p)代替st,st

什么类型的指针指向什么类型的数

int a;int *p;

char ch,char *q;

2.格式:

数据类型 (*函数指针变量名)(参数);

3.用法:

1)当一个函数指针指向了一个函数,就可以通过这个指针来调用该函数,

2)函数指针可以将函数作为参数传递给其他函数调用。

代码示例(如下):

#include <stdio.h>
#include <signal.h>
void fun(int sig)
{
    printf("***************\n");
}
int main(int argc, char const *argv[])
{
    signal(SIGINT, fun);//同步运行,若while在sianal()上边,直接执行死循环,不会调用子函数
    while (1);//异步运行

    return 0;
}

4.指针函数和函数指针分别在什么地方用过?

1)指针函数

当需要这个函数返回地址时。

2)函数指针

signal函数参数 (信号处理函数)

pthread_create函数的参数 (线程的处理函数)

底层(file_operations结构体里成员())

5.要求:

1:知道函数指针,能倒退还原函数

2:有函数,要让指针指向这个函数,要能定义出函数指针

注意:数据类型(返回值的数据类型,参数的数据类型)

代码示例(如下):

#include <stdio.h>
int add(int i, int j);//函数声明(格式一致)
int fun(int a, int (*p)(int b, int c));//函数声明(格式一致)
int main(int argc, char const *argv[])
{
    printf("%d\n", fun(10, add)); //函数首地址
    return 0;
}
int add(int i, int j)
{ //形参被实参覆盖
    return i + j;
}
//两个参数:第一个整型,第二个函数指针
int fun(int a, int (*p)(int b, int c))
{
    return a + p(3, 5); //定义实参
}


// 18

【4】函数指针数组

1.本质:

数组,数组的内容为函数指针

2.格式:

数据类型 (*函数指针数组名[个数])(参数);

代码示例(如下):

#include <stdio.h>
int add(int a, int b)
{
    return a + b;
}
int fun(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a * b;
}
int main(int argc, char const *argv[])
{
    int (*p[3])(int, int) = {add, fun, mul};//函数指针数组
    int i = 0;
    for (i = 0; i < 3; i++)
    {
        printf("%d\n", p[i](3, 2));
    }
    return 0;
}


// 5
// 1
// 6

【5】解决问题—>准确定位(行)

使用过的调试方式有哪些?

1:GDB

(在用GDB调试之前确定你的代码没有语法错误。设置断点的时候,必须让主函数运行起来,第一次断点设置,设置在主函数当中的某一行,这样编译器才能从入口函数进来)

在gcc编译选项中一定要加入‘-g’。

只有在代码处于“运行”或“暂停”状态时才能查看变量值。

设置断点后程序在指定行之前停止

1) gcc -g test.c

2) gdb a.out

3)(gdb)l:列出源文件内容

4)(gdb)b 10:设置断点在第10行

5)(gdb)r :运行(设置断点后一定要先运行,才能进行单步调试往下)

6)(gdb)n:单步调试(断点行是不被运行的,n单步调试的时候不进子函数)

7)(gdb)s:单步运行(断点行是不被运行的,s单步调试的时候进子函数)

8)(gdb)p 变量名 :查看变量值

9) q:退出调试界面

2:printf打印

printf("%s,%s,%d\n",__FILE__,__func__,__LINE__);

1)大概定位(缩小范围)

2)作用:定位错误。

        如果这一行打印,那么引起错误的代码肯定在这一行之

        如果这一行没有打印,那么引起错误的代码肯定在这一行之

代码示例(如下):

#include <stdio.h>
#include <string.h>
int fun()
{
    int i = 3;
    int j = 4;
    printf("i:%d j:%d\n", i, j);
}
int main(int argc, char const *argv[])
{
    fun();
    int a = 3;
    int b = 4;
    char *p = NULL;
    printf("%s %s %d\n", __FILE__, __func__, __LINE__); 
    //无法定位到哪一行,只能缩小范围(名文件_函数名_行数)
    strcpy(p, "hello");
    printf("%s\n", p);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值