基于Linux学习 C语言——基础 DAY12

 一、二维数组和指针

 

 1.1数组指针

由于一级指针存不了二维数组的地址,于是有了数组指针,本质上是个指针

    值:arr[i][j]-->*(*(arr+i)+j)-->*(*(&arr[0]+i)+j)-->*(arr[i]+j)
    :p[i][j]-->*(*(p+i)+j)-->*(*(&p[0]+i)+j)-->*(p[i]+j)

    地址:&arr[i][j]-->*(arr+i)+j-->*(&arr[0]+i)+j-->arr[i]+j
    :&p[i][j]-->*(p+i)+j-->*(&p[0]+i)+j-->p[i]+j

 练习:打印二维数组中所有数据及地址

#include<stdio.h>
int main() {
	int arr[2][3] = { 1,2,3,4,5 };
	int (*p)[3]= arr;
	int len= sizeof(arr) / sizeof(arr[0]);
	printf("%d\n",len);
	for (int i = 0; i < len;i++) {
		for (int j = 0; j < 3; j++) {
			printf("%d ", *(*(p+i)+j));
		}
		printf("\n");
	}
	for (int j = 0; j < len; j++) {
		for (int i = 0; i < 3; i++) {
			printf("%p ", *(p + i) + j);
		}
		printf("\n");
	}
}

1.2指针数组

练习 :遍历指针数组

#include <stdio.h>

int main() {
	int a[3] = { 1,2,3 }, b[3] = { 1 ,59,6 }, c[5] = { 0 };
	int* p[3] = { a,b,c };
	int sizes[3] = { 3, 3, 5 };  // 数组的大小
	// 外层循环遍历指针数组
	for (int i = 0; i < 3; i++) {
		// 内层循环遍历每个数组
		for (int j = 0; j < sizes[i]; j++) {
			printf("Array %d, Element %d = %d\n", i + 1, j + 1, p[i][j]);
		}
	}
	return 0;
}

 1.3字符指针数组

1> 字符指针数组存储多个字符数组的地址
    char str1[]="ASDF",str2[]="abcde",str3[]="12",str4[]="!@#";
    char *p[]={str1,str2,str3,str4};
    //         
    printf("%s\t",str1);
    *(*p+1)='s';//可以发生更改
    int len=sizeof(p)/sizeof(p[0]);
    for(int i=0;i<len;i++)
    {
    printf("%s\n",*(p+i));
    }
    
    
 
2> 字符指针数组存储多个字符串常量的地址
char *q[]={"ASDF","abcde","12","!@#"};
//    *(*q+1)='s';段错误
len=sizeof(q)/sizeof(q[0]);
    for(int i=0;i<len;i++)
    {
    printf("%s\n",*(q+i));
    }

 1.4指针函数

 实现strcpy函数

#include<stdio.h>

char *my_strcpy(char *dest, const char *src) {
	char* ret = dest;
	while (*dest++ = *src++);
	return ret;
}

int main() {
	char a[]= "hello";
	char b[]= "world";
	printf("%s\n",my_strcpy(a, b));
}

1.5函数指针

 

 示例:

#include<stdio.h>

int my_add(int x,int y) {
	return x + y;
}

int my_sub(int x,int y) {
	return x - y;
}


int main() {
	int m=20;
	int n=10;
	printf("my_add(m,n)=%d\n",my_add(m,n));
	printf("my_sub(m,n)=%d\n",my_sub(m,n));

	//定义函数指针的格式
	//	返回值类型	(*函数指针名)(函数的形参列表)
	int (*p1)(int,int)=my_add;//函数名就是函数的地址
	int (*p2)(int,int)=my_sub;
	//定义了一个函数指针	可以指向返回值为int类型,形参列表为(int,int)类型的函数

	//当函数指针指向了一个函数之后,可以通过函数指针来调用函数
	printf("p1(m,n)=%d\n", p1(m, n));//30
	printf("p2(m,n)=%d\n", p2(m, n));//10
	return 0;
}

而函数指针也多用于回调函数当中:

#include<stdio.h>

int my_add(int x,int y) {
	return x + y;
}

int my_sub(int x,int y) {
	return x - y;
}

int jisuan(int x,int y,int (*p)(int,int)) {
	//函数内部通过指针调用函数时,具体调用哪个函数
	//取决于 用户在调用jisuan函数时,传递的第三个参数
	//传什么函数,就调用什么函数 所以叫做回调函数
	return p(x, y);
}

int main() {
	int m=20;
	int n=10;
	int ret1 = jisuan(m, n, my_add);
	printf("ret1 = %d\n", ret1);//30
	int ret2 = jisuan(m, n, my_sub);
	printf("ret2 = %d\n", ret2);//10
	return 0;
}

1.6函数指针数组 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int add(int a,int b)//100 10
{
    return a+b;
}
int sub(int a,int b)
{
    return a-b;
}
int mul(int a,int b)
{
    return a*b;
}
int divs(int a,int b)
{
    return a/b;
}

int main(int argc, const char *argv[])
{
    int a=100,b=10;

    
 //需要使用4个函数指针
    int (*p1)(int,int)=add;
    int (*p2)(int,int)=sub;
    int (*p3)(int,int)=mul;
    int (*p4)(int,int)=divs;

    int (*p[4])(int,int)={add,sub,mul,divs};
    for(int i=0;i<4;i++)
    {
    int s=(*(p+i))(a,b);
    printf("s=%d\n",s);
    }
    return 0;
}

1.7 多级指针

一级指针存储变量的地址

二级指针存储一级指针的地址

三级指针存储二级指针的地址

1.8通用类型指针 

通用类型指针,可以指向任意一种类型的指针,可以指向任意一块地址,但是在使用时,必须进行类型强转。

格式: void *指针变量名

一般用来传参时使用,c基础阶段用得比较少

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值