函数和指针

1、指针与函数的返回值

 1 #define A 0
 2 int funcA(int a, int b)
 3 {
 4     return a + b;
 5 }
 6
 7 /*把指针作为函数的返回值*/
 8 int * funcB(int a, int b)
 9 {
10     static int c = A;
11     c = a + b;
12     return &c;
13 }
14 /*通过函数进行内存的申请*/
15 /*
16 * 参数:要申请的内存大小
17 * 返回值:申请好的内存的首地址
18 * 这是一种不好的方式
19 */
20 int * funcC(int size)
21 {
22     return (int *)malloc(size);
23 }
24 /*通过函数进行内存的申请*/
25 /*
26 * 参数:要申请的内存能够保存多少个int变量
27 * 返回值:申请好的内存的首地址
28 */
29 int * funcD(int sum)
30 {
31     return (int*)malloc(sizeof(int)* sum);
32 }
33
34 /*函数返回值测试*/
35 int main001(int argc, char **argv)
36 {
37     int *p_int, temp;
38     p_int = funcB(2, 5);
39     printf("%d \n", *p_int );
40
41     temp = *funcB(4, 8); /*这样写是不推荐的形式*/
42
43     /* &temp = funcB(5, 7); */ /*这样是错误的*/
44
45
46     system("pause");
47     return 0;
48 }
49
50 int main(int argc, char **argv)
51 {
52     int* p_int;
53
54     /*想想看,前面声明的哪个函数原型合理?*/
55     p_int = funcC(20);
56     for (int i = 0; i < 20 / sizeof(int); i++)
57     {
58         p_int[i] = i;
59     }
60     p_int = funcD(5);
61     for (int i = 0; i < 5; i++)
62     {
63         p_int[i] = i;
64     }
65     system("pause");
66     return 0;
67 }

指针与函数的返回值

2、指针和函数的参数

函数传参的两种方式:传值和传址

如果是传值,在被调函数内部不能改变主调函数变量的值。

如果是传址,在被调函数内部可以通过地址来操作外部的变量。

3、函数指针

指向函数的指针

函数名称本身就是一个函数指针。

比如:int (*p_func)(int)

第一个int是返回值,p_func函数指针的名称,(*p_func) 考虑到匹配优先级问题,要加括号,第二个int是函数指针对应函数的参数。

函数指针的意义,从内存中找到需要执行的代码对应的首地址,

注意,函数指针的类型要与其指向的函数原型相吻合

函数申请与释放内存

1、 malloc

2、 realloc

3、 calloc  申请内存后帮助我们初始化内存的内容,其余和malloc功能完全一样

4、 free 释放内存

应用:回调函数

实现回调函数机制的流程:

A、 首先需要一个主调函数,他至少要有一个参数是函数指针。

B、 实现回调函数,回调函数的 函数原型必须要和主调函数中函数指针的类型相匹配

C、 根据业务需要或具体情况决定该传入哪一个函数指针

 1 int clock(int time)
 2 {
 3     if (time == 6)
 4     {
 5         printf("零零零零。。。。\n");
 6         return 1;
 7     }
 8     else
 9     {
10         printf("我不出声,只是看着你。。。\n");
11         return 0;
12     }
13
14 }
15 /*父母的行为*/
16 int parent(int time)
17 {
18     if (time >= 6)
19     {
20         printf("太阳晒屁股了,快起床!\n");
21         return 1;
22     }
23     else
24     {
25         printf("我是不叫醒呢,不叫醒呢,还是不叫醒呢。。。\n");
26         return 0;
27     }
28
29 }
30 /************************************************************************/
31 /* 定义主调函数                                                                     */
32 /************************************************************************/
33 /*触发唤醒*/
34 int weakup(int(*p_func)(int), int time)
35 {
36     if (!p_func(time)) /*没有到时间*/
37     {
38         printf("zzzzzzzzzzzzzzzzz\n");
39         return 0;
40     }
41     else
42     {
43         if (time == 6)
44         {
45             printf("再睡一会儿。。。\n");
46             return 0;
47         }
48         else
49         {
50             printf("好吧,你赢了,我起床。。。");
51             return 1;
52         }
53     }
54
55 }
56
57 /*处理主框架,决定主调函数使用哪个函数指针*/
58 int main(int argc, char** argv)
59 {
60     for (int i = 0; i <= 24; i++)
61     {
62         printf("当前时间:%d\n", i);
63         if (weakup(clock, i))
64         {
65             break;
66         }
67
68         if (weakup(parent, i))
69         {
70             break;
71         }
72     }
73     system("pause");
74     return 0;
75 }

示例

多重指针

二级指针

指向指针的指针,它本身也是一个指针,类型是指向的那个指针类型的指针类型。

 1 int main()
 2 {
 3    /* int a = 100;
 4     int *b = &a;
 5     int **c = &b;
 6     */
 7     int a;
 8     int *b;
 9     int **c;
10     a = 100;
11    // *b = a;错误写法 b是一个地址,*b是从一个地址中取出的常量。
12     b = &a;
13     c = &b;
14
15     printf("a=%d\tb=%d\tc=%d\n",a,*b,**c);
16     printf("a=%p\tb=%p\tc=%p\n",&a,b,c);
17     printf("a=%p\tb=%p\tc=%p\n",&a,&b,&c);
18
19     return 0;
20 }

二级指针的用途:

二级指针用作函数的输出参数,可以返回函数内申请的内存地址。

 1 /*二级指针用途*/
 2
 3 /*一级指针做内存申请实验*/
 4 int funcA(int * p_int)
 5 {
 6     p_int = (int *)malloc(sizeof(int)* 10);
 7     return 0;
 8 }
 9
10 /*二级指针做内存申请实验*/
11 int funcB(int ** pp_int)
12 {
13     *pp_int = (int*)malloc(sizeof(int)* 10);
14     printf("*pp_int = %p\n", *pp_int);
15     return 0;
16
17 }
18
19 int main(int argc, char** argv)
20 {
21     int *p_int1 = NULL;
22     int *p_int2 = NULL;
23     printf("p_int1 = %p, p_int2 = %p\n", p_int1, p_int2);
24     funcA(p_int1);
25     funcB(&p_int2);
26     printf("p_int1 = %p, p_int2 = %p\n", p_int1, p_int2);
27
28     system("pause");
29     return 0;
30 }

二级指针的用途

p_int1 = 0x7ffc45c421e0, p_int2 = 0x7ffc45c421e4
*p_int = 0x55aabf873670
*pp_int = 0x55aabf8736a0
p_int1 = 0x7ffc45c421e0, p_int2 = 0x55aabf8736a0

二级指针生成二维数组

前置知识点:

指针数组:数组的内容是指针类型。

例:定义一个整型指针的数组  int* arr_int[10];

指针类型数组元素都是指针类型的,当我们把指针类型的元素全都指向有意义的内存空间时,就可以使用二级指针来生成二维数组了

 1 int main(int argc, char** argv)
 2 {
 3     /*首先定义一个二级指针变量*/
 4     int ** pp_arr = NULL;
 5
 6     /*先生成数组的第一维*/
 7     pp_arr = (int**)malloc(sizeof(int*) * 4 );
 8
 9     /*通过循环生称第二维*/
10     for (int i = 0; i < 4; i++)
11     {
12         //元素类型是一级指针
13         pp_arr[i] = (int*)malloc( sizeof(int)* 10);  /*第二维数组长度为10*/
14
15     }
16     /*到此为止,使用二级指针生称了二维数组*/
17
18     for (int i = 0; i < 4; i++)
19     {
20         for (int j = 0; j < 10; j++)
21         {
22             pp_arr[i][j] = rand();
23         }
24     }
25
26     /*打印出数组内容*/
27     for (int i = 0; i < 4; i++)
28     {
29         for (int j = 0; j < 10; j++)
30         {
31             printf("[%d]", pp_arr[i][j]);
32         }
33         printf("\n");
34     }
35     system("pause");
36     return 0;
37 }

二级指针生成二维数组

原文地址:https://www.cnblogs.com/hhzc/p/9141863.html

时间: 2024-10-01 20:32:39

函数和指针的相关文章

类的成员函数的指针

前面一篇文章<函数的指针 >介绍了全局函数的指针,现在我们再来介绍一下成员函数的指针. 成员函数指针的定义: 一般形式 Return_Type (Class_Name::* pointer_name) (Argument_List); 用typedef简化的形式 Typedef Return_Type (Class_Name::* FuncPtr_Type) (Argument_List); FuncPtr_Type pFunc = NULL; //pFunc为成员函数指针的指针变量 成员函数

【C++】函数和指针

最近在看C++ primer plus,感觉函数与指针这一章难点比较多,记写笔记,加强理解. From C++ Primer Plus: Chapter 7 Function:C++ Programming Modules 1. 如何声明函数指针? 和函数原型类似: 需要声明指针指向函数的返回值和参数列表 double pam(int); //参数为int 类型,返回值为double 类型的函数 double (*pf);(int) //指向参数为int类型,返回值为double 类型的指针 p

成员函数指针和指向静态成员函数的指针

#include <iostream> using namespace std; class Student{ public:     Student(const string& name):m_name(name){}     void who(void){         cout << m_name << endl;     }     string m_name;     static int s_add(int a,int b){         re

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

指针实现两数交换和指向函数的指针

指针就是地址,而指针变量就是存储地址的变量. 1.指针与函数 利用指针解决: C语言中函数的参数采用"单向传递",故第一个程序中改变形参不会改变实参,而在第二个程序中,使用指针变量作为参数,改变指针变量所指向的值,函数调用结束后,变量值被保留下来. 2.指向函数的指针的应用

函数和指针 C++

一.用函数指针变量调用函数. 指针变量也可以指向一个函数,一个函数在编译时被分配给一个入口地址.这个函数入口地址就称为函数的指针.可以用一个指针变量指向函数,然后通过该指针变量调用此函数. 定义指向函数的方法,格式是: int (*p)(int,int);     函数名代表函数入口地址,而max(a,b)则是函数调用. 二.返回指针值的函数 一个函数可以带回一个整数值.字符值.实型值等,也可以带回指针型的数据,即地址.其概念和以前类似,只是带回的值是指针类型而已.返回指针值的函数简称为指针函数

c++: 指向类成员函数的指针

指向函数的指针有和指向类成员函数的指针的有什么不同? int f(char a, float b);如果它是普通函数,则它的类型是 int (*)(char, float);如果它是非静态成员函数,则它的类型是 int(ClassName::*)(char, float);如果它是静态成员函数,则它的类型是和普通函数一样. 如何把一个类的成员函数传递给event handler, 线程启动函数等? 类的成员函数必须和一个类的实例结合起来才有意义.可以写一个函数来包装类的成员函数. class X

iOS指向函数的指针和block

  一:block基础知识 block基础知识 基本概念:block是用来保存一段代码的:^:是block得标志  好比*:是指针的标志 特点:1:保存一段代码: 2:可以有参数和返回值: 3:可以作为函数的参数传递: 与代码块的区别,代码块里的代码会自动执行,block中代码要手动调用: 二:普通数据类型.指向函数的指针.block的定义的类比 1:基本数据类型: 例如:int a = 10; 格式:数据类型  变量名 = 值: 2:指向函数的指针:可以仿照上边基本数据类型的定义 例如:voi

c 函数及指针学习 10

标准库函数 1算数运算stdlib.h 2随机数stdlib.h 3字符串转化stdlib.h 4数学函数 math.h 5日期和时间 time.h 6信号 signal.h 7打印可变参数列表stdarg.h 8断言 assert.h 抽象数据类型在数据结构中比较仔细 运行时环境没看 来自为知笔记(Wiz)c 函数及指针学习 10,码迷,mamicode.com

数组、函数和指针

一.数组和指针 数组名同时也是该数组首元素的地址.例如:flizny == &flizny[0] , flizny 和 &flizny[0]都代表首元素的内存地址,两者都是常量: 指针+1的结果就是对该指针增加一个存储单元,对于数组而言,地址会增加到下一元素的地址,而不是下一个字节. 可以用以下等式表示: dates + 2 == &date[2] // 相同的地址 *(dates + 2) == dates[2] //相同的值 二.函数和指针 由于数组名就是数组首元素的地址,所以