C语言-Day11

一、数组指针

1.数组指针本质上是一个指针变量,用于存储整个数组的起始地址;

2.对于数组指针而言,指针每偏移一个单位,内存就会偏移整个数组容量的大小;

3.数组指针一般用于二维数组,二维数组的数组名,本质上是一个数组指针常量;

4.数组指针的定义格式:数据类型 (*数组指针名)[常量];

例: int arr[5]={2,3,4,6,7};

        int(*arr_ptr)[5];  //定义一个数组指针变量,变量名为arr_ptr

         arr_ptr=&arr;       //数组指针指向该数组

#include<myhead.h>
 
int main(int argc, const char *argv[])
{
	int arr[5] = {4,8,3,2,6};
 
	printf("sizeof(arr) = %ld\n", sizeof(arr));
	printf("sizeof(&arr[0]) = %ld\n", sizeof(&arr[0]));
	printf("sizeof(&arr) = %ld\n", sizeof(&arr));
 
	//从数值上来说,这三个地址都一样
	printf("arr = %p, &arr[0] = %p, &arr = %p\n", \
			arr, &arr[0], &arr);
 
	printf("arr+1 = %p, &arr[0]+1 = %p, &arr+1 = %p\n", \
			arr+1, &arr[0]+1, &arr+1);
 
	//定义一个数组指针指向 arr
	int (*arr_ptr)[5] = &arr;
 
	printf("数组元素分别是:");
	for(int i=0; i<1; i++)
	{
		for(int j=0; j<5; j++)
		{
			printf("%d\t", arr_ptr[i][j]); // *((*arr_ptr+i)+j)
		}
		printf("\n");
	}
 
	for(int i=0; i<5; i++)
	{
		printf("%d\t", arr_ptr[0][i]);
	}
	printf("\n");
 
 
 
 
	return 0;
}
 
#include<myhead.h>
 
int main(int argc, const char *argv[])
{
	
	int arr[3][4] = {{1,2,3,4},{2,2,3,4},{4,4,4,4}};
	//输出对应的地址
	printf("&arr[0][0] = %p\n", &arr[0][0]);    //普通变量的地址
	printf("arr[0] = %p\n", arr[0]);            //第一个数组数组名
	printf("arr = %p\n", arr);                  //第一个数组的地址
 
	printf("****************************************\n");
	printf("&arr[0][0]+1 = %p\n", &arr[0][0]+1);    //普通变量的地址
	printf("arr[0]+1 = %p\n", arr[0]+1);            //第一个数组数组名
	printf("arr+1 = %p\n", arr+1);                  //第一个数组的地址
 
	//从上述代码可以看出,arr是一个数组的起始地址,可以定义一个数组指针存放
	int (*arr_ptr)[4] = arr;
 
	//输出数组元素
	printf("数组元素分别是:\n");
	for(int i=0; i<3; i++)
	{
		for(int j =0; j<4; j++)
		{
			printf("%d\t", *(*(arr_ptr+i) + j));     //arr_ptr[i][j]
		}
		printf("\n");
	}
 
 
	return 0;
}
 

 二、指针数组

1.本质上是一个数组,其中的元素为指针变量

2.格式定义:数据类型 * 数组名[数组长度];

3.案例

#include<myhead.h>
 
int main(int argc, const char *argv[])
{
	//定义多个变量
	int num = 520;
	int key = 1314;
	int value = 999;
 
	//定义指针数组存储上面多个变量的地址
	int *ptr_arr[3];        //此时定义了三个指针变量,分别是 ptr_arr[0]
							//ptr_arr[1] ptr_arr[2]
	//给指针变量赋值
	ptr_arr[0] = &num;
	ptr_arr[1] = &key;
	ptr_arr[2] = &value;
 
	//通过指针数组操作数据
	for(int i=0; i<3; i++)
	{
		printf("%d\t", *ptr_arr[i]);      //输出值
	}
	printf("\n");
 
	printf("&num = %p, &key = %p, &value = %p\n", &num, &key, &value);
	for(int i=0; i<3; i++)
	{
		printf("ptr_arr[%d] = %p\t",i , ptr_arr[i]);
	}
	printf("\n");
 
	return 0;
}
 

三、指针函数

1.指针函数本质上是函数,函数的返回值类型是指针类型;

例如: char *strcpy();

2.定义格式:返回值类型 * 函数名(形参列表){函数体内容}

3.注意:返回值为指针类型的函数,返回结果是一个左值,函数调用的结果可以放在等号左侧

4.函数返回的地址,只能是生命周期比较长的存储空间的地址

        1>全局变量

        2>静态局部变量

        3>主调函数以地址的形式传递到被调函数中的那块内存;

                例如:char *strcpy();

        4>使用malloc函数动态申请的堆区空间;

#include<myhead.h>
 
//定义指针函数
int *fun()
{
	static int num = 520;
 
 
	return &num;
}
 
 
 
/************************主程序********************/
int main(int argc, const char *argv[])
{
	int *ptr = fun();    //定义指针接受返回结果
 
	*ptr = 1314;
 
	printf("*fun() = %d\n", *fun());      //1314
 
	*fun() = 999;         //对指针函数中的内容改变
	printf("*ptr = %d\n", *ptr);      //?
 
	return 0;
}

四、函数指针

1.函数指针本质上是一个指针,指向函数的入口地址;

2.任何函数执行,系统都会在栈区为其分配一块用于执行的运行空间,有内存空间,就会有起始地址

#include<myhead.h>
 
//定义求和函数
int sum(int m, int n)
{
	return m+n;
}
 
 
int main(int argc, const char *argv[])
{
	int num  = 520;
	int key = 1314;
 
	printf("result = %d\n", sum(num, key));   //函数调用
	printf("sum = %p\n", sum);    //函数名是函数入口地址
 
	//定义函数指针,存储函数入口地址
	int (*ptr_sum)(int, int);   //此时定义了一个指针,该指针
						//指向一个返回值为int类型,参数为两个int类型的函数入口地址
	ptr_sum = sum;       //此刻之后,所有使用sum的地方,都可以改成ptr_sum
	printf("result = %d\n", ptr_sum(num, key));   //函数调用
 
 
	
 
	return 0;
}
 

3.函数的名字就是函数的入口地址,如果想将函数作为另一个函数参数的话,可以用函数指针变量来接收,也就是所谓的回调函数;

4.用处:多线程创建时用到(IO进程线程)、数据库执行sql语句时用到(网络编程)、信号处理函数调用时会用到(IO进程线程);

5.函数指针的定义格式:数据类型(*指针名)(参数类型);

#include<myhead.h>
//定义求和函数
int jiafa(int m, int n)
{
	return m+n;
}
 
 
//定义求差函数
int jianfa(int m, int n)
{
	return m-n;
}
 
//定义求乘积函数
int changfa(int m, int n)
{
	return m*n;
}
 
//定义计算函数
void jisuan(int x, int y, int (*ptr)(int, int))
{
	printf("计算结果为:%d\n", ptr(x, y));    //完成函数回调
}
 
 
 
int main(int argc, const char *argv[])
{
	int m = 520;
	int n = 1314;
 
	//调用计算函数
	jisuan(m, n, jiafa);
	jisuan(m, n, jianfa);
	jisuan(m, n, changfa);
 
 
	
 
	return 0;
}
 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值