C语言--指针以及结构体的知识点补充

文章介绍了C语言中指针与函数的关系,包括指针函数的原理和问题,以及如何通过使用`static`关键字解决栈区空间释放导致的问题。此外,还详细讲解了函数指针的概念,如何定义和使用,以及在回调函数中的应用。同时,提到了指针数组和数组指针的区别,并通过示例解释了二维数组在内存中的表示和大小计算。
摘要由CSDN通过智能技术生成
  • 指针与函数

指针函数:本质上这是一个函数,但函数的返回值是指针

例:

#include <stdio.h>
char* fun()
{
    char str[] = "hollow world";  //栈区开辟的空间会随着函数周期的结束将空间释放
    return str;                   //

}
int main()
{
    char* p;
    p = fun();
    printf("p=%s\n",p);
    return 0;
}

打印的并不是字符串,而是一串乱码。什么原因呢?

栈区开辟的空间会随着代码段的结束而释放 ,那如何来修改

#include <stdio.h>
char* fun()
{
     static char str[] = "hollow world";
         //通过static来将其放入静态区,静态区的空间不会随着代码段的结束而释放空间。
    return str;

}
int main()
{
    char* p;
    p = fun();
    printf("p=%s\n",p);
    return 0;
}

总结:返回的地址,地址指向的内容得存在才有意义。

  • 函数指针----用来存放函数的入口地址--即函数名

C语言规定:函数名就是函数的首地址,即函数的入口地址。那么我们可以定义一个指针变量来存放函数的入口地址,这个指针变量就叫做函数指针。

函数指针的定义:

返回值类型 (*指针类型)(形参)

调用函数时,跟函数名一个用法。

int fun(int a,int b)//定义一个函数
{



}
int (*p)(int x,int y)
{


}
//调用函数
fun(1,2);
//或者
p(1,2);



函数指针数组

int (*p[10])(int x , int y)//数组元素有10个,存放的是函数指针,函数指针存放的是函数的地址

函数指针最常用的地方---当函数需要作为参数传递时----回调函数

#include <stdio.h>

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

int sub(int a, int b)
{
    return a - b;
}
int mux(int a, int b)
{
    return a * b;
}
int prog(int (*p)(int,int),int a,int b)//定义一个函数指针来接受 其他函数的入口地址
{
    int ret =  p(a, b);//等价与 int ret = p(a,b); 调用函数时 函数指针变量()等价于函数名()
}
int main()
{
    int num = prog(add, 1, 2);
    printf(" num=%d\n", num);
    return 0;
}//打印3

  • 函数指针 --指针函数--函数指针数组小结

函数指针----本质是指针,指针存放的必然是地址,因此函数指针存放的是函数的入口地址--函数名就是函数的入口地址。-----常用在函数传参--场景:回调函数

指针函数---本质上是函数,函数的返回值是指针--函数的返回值是地址,地址得用指针接收

定义: 指针类型 函数名(形参)

函数指针数组---本质是数组,数组里面放的是函数指针---指针指向的是函数的入口地址。

  • 指针数组和数组指针

指针数组--本质是数组--数组里面存放的是指针

int * p[10]

数组指针--本质是指针--存放数组的地址--常用在二维数组的传参

int (*p)[10]---指针p的访问大小为int[10]

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

void  main()
{
    int a[3][4] = { 0 };
    //定义一个3行4列的数组
    printf("%d\n", sizeof(a));
    //a是二维数组的数组名,代表首行的地址,但是在sizeof(数组名),计算整个数组的大小---48
    printf("%d\n", sizeof(a[0][0]));
    //a[0][0]找到二维数组第一行第一列的元素---4
    printf("%d\n", sizeof(a[0]));
    //指向第一行第一列的地址,但是其相当于第一行的数组名,因此计算的是整行数组的大小---16
    printf("%d\n", sizeof(a[0] + 1));
    //第一行的第二个元素地址,相当于列指针----4字节
    printf("%d\n", sizeof(*(a[0] + 1)));
    //第一行数组的第二个元素大小--4
    printf("%d\n", sizeof(a + 1));
    //第二行的地址---4个字节
    printf("%d\n", sizeof(*(a + 1)));
    //指向第二行第一列的地址,但是相当于数组名  因此计算的是整个数组大小 16
    printf("%d\n", sizeof(&a[0] + 1));
    //a[0]是第一行第一列的地址,相当于数组名 ,&数组名+1,取出第二行的地址,相当于数组指针--4字节
    printf("%d\n", sizeof(*(&a[0] + 1)));
    //第二行的数组名--16
    printf("%d\n", sizeof(*a));
    //第一行第一列的地址,相当于第一行的数组名---16
    printf("%d\n", sizeof(a[3]));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值