Day10-C语言 自定义函数,实现杨辉三角,要求使用数组指针做参数

自定义函数,实现杨辉三角,要求使用数组指针做参数

1.9 二维数组和指针

 i)二维数组地址

&arr[0][0]: 表示第一个元素的地址,偏移一个数据类型字节大小,列偏移

arr[0]: 等价于一维数组数组名,表示第一行第一个元素的地址,偏移一个数据类型字节大小,列偏移

&arr[0]:等价堆一维数组数组名取地址,表示一行的首编号,偏移一行字节大小,行偏移

arr: 二级地址,表示行偏移,偏移一行字节大小

&arr: 表示整个二维数组的地址,偏移整个二维数组

 ii)二维数组和指针

int main(int argc, const char *argv[])
{
    int arr[2][3]={11,22,33,44,55,66};


    //int *p=arr; 原因:arr是二级地址,p是一级指针,不等价
    int (*p)[3]=arr;//p==arr
    printf("&p[0][0]=%p\t&p[0][0]+1=%p\n",&p[0][0],&p[0][0]+1);
    printf("p[0]=%p\tp[0]+1=%p\n",p[0],p[0]+1);
    printf("&p[0]=%p\t&p[0]+1=%p\n",&p[0],&p[0]+1);
    printf("p=%p\tp+1=%p\n",p,p+1);
    printf("&p=%p\t&p+1=%p\n",&p,&p+1);
}

    //arr:  第一行的行地址
    //2行3列
    //arr+1   第二行行地址
    //
    //*(arr+1) 地二行第一列的列地址
    //*(arr+1)+2     第二行地三列的列地址
    //*( *(arr+1)+2 ) 2行3列的元素
    //i+1行i+1列的元素:   *(*(arr+i)+j)
    //&arr[0][0]===arr[0]
    //&arr[0]====arr
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<3;j++)
        {
//        printf("%d\t",arr[i][j]);
//        printf("%d\t",*(*(arr+i)+j));//*(arr+i)-->arr[i]
//        printf("%d\t",*(*(&arr[0]+i)+j));
//        printf("%d\t",*(arr[i]+j));
//        printf("%d\t",p[i][j]);
//        printf("%d\t",*(*(p+i)+j));//*(arr+i)-->arr[i]
//        printf("%d\t",*(*(&p[0]+i)+j));
//        printf("%d\t",*(p[i]+j));

        }
        printf("\n");
    }
    //值: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)

    for(int i=0;i<2;i++)
    {
        for(int j=0;j<3;j++)
        {
            
                printf("%p\t",&arr[i][j]);
                printf("%p\t",*(arr+i)+j);

                printf("%p\t",*(&arr[0]+i)+j);
                printf("%p\t",arr[i]+j);
                printf("%p\t",&p[i][j]);
                printf("%p\t",*(p+i)+j);

                printf("%p\t",*(&p[0]+i)+j);
                printf("%p\t",p[i]+j);

        }
        printf("\n");
    }
    //地址:&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

    return 0;
}

值: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

1.10 数组指针

本质上就是一个指针,主要用来指向二维数组地址,或者做参数接受二维数组地址。

格式:存储类型 数据类型 (*指针变量名)[常量表达式] ()>[]>*

int arr[2][3];

int (*p)[3]=arr; p=arr

解析:

1.数组指针,指向以3个元素为一行的首地址编号,指向的是一维数组的整体数组的地址

2.() []: 不可以省略

3.常量表达式:需要和二维数组列保持一致

 

1.11指针数组

本质上是一个数组,每个元素存储的是指针

格式: 存储类型 数据类型 *指针数组名[常量表达式]

 

int main(int argc, const char *argv[])
{
    /*
    int a=1,b=2,c=3,d=4;
    int *p1=&a,*p2=&b,*p3=&c,*p4=&d;

    int *p[4]={&a,&b,&c,&d};
    //p[0]=&a
    //p[1]=&b
    printf("a=%p  b=%p  c=%p  d=%p\n",&a,&b,&c,&d);
    for(int i=0;i<4;i++)
    {
        printf("%d\t",*p[i]);
    }
    printf("%ld\n",sizeof(p));*/
    int a[3]={1,2,3},b[]={4,5,6},c[]={7,8,9};
    int *p[3]={a,b,c};
    for(int i=0;i<3;i++)
    {
    for(int j=0;j<3;j++)
    {
        printf("%d\t",*(*(p+i)+j));
    }
    printf("\n");
    }

    return 0;
}

 

1.12 字符指针数组

本质上是一个数组,指向多个字符串的地址。

格式: char *指针数组名[常量表达式]

char *p[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));
    }
 
 练习主函数:在终端输入,使用字符指针数组
 int main(int argc, const char *argv[])
{
    //argc: 命令行输入字符串的个数
    //argv:  存储命令行输入的每一个字符串
    printf("argc=%d\n",argc);
    for(int i=0;i<argc;i++)
    {
    printf("%s\n",*(argv+i));
    }

    return 0;
}
   
运行结果:
ubuntu@ubuntu:pointer$ gcc main.c 
ubuntu@ubuntu:pointer$ ./a.out aaa bbb ccc
argc=4
./a.out
aaa
bbb
ccc

1.13 指针函数

本质上是一个函数,主要是返回一个地址

格式:存储类型 数据类型 *函数名(参数列表)

char *strcpy(char *dest, const char *src);

需求:
    /*返回局部变量的地址:段错误    
int *fun()
{
    int a=100;
    int b=1;
    int arr[2];//局部变量 调用fun函数arr分配空间,函数调用结束arr空间释放   0x10-0x17
arr[0]=a;
arr[1]=b;
    return arr;//0x10
}*/

 解决方法:
/*
 *方法1:
int arr[2];//数组定义为全局变量
int *fun()
{
    int a=100;
    int b=1;
arr[0]=a;
arr[1]=b;
    return arr;//0x10
}*/
/*
 * 常使用    方法2:
int *fun(int arr[2])//arr=0x20
{
    int a=100;
    int b=1;
arr[0]=a;
arr[1]=b;
    return arr;//0x20
}*/
方法3:
int *fun()//arr=0x20
{
    int a=100;
    int b=1;
    int *p=(int *)malloc(10);//p指向堆区10个字节的首地址   0x10-0x19
    *p=a;
    *(p+1)=b;
    return p;//0x10
}
int main(int argc, const char *argv[])
{
    int arr[2];//0x20
    int *p=fun();//0x20
    printf("a=%d\n",*p);
    printf("a=%d\n",*(p+1));
    return 0;
}

练习:字符串拷贝,返回拷贝后的地址
     char *strcpy(char *dest,  char *src)
     {
         int i;
         for(i=0;*(src+i)!='\0';i++)
         {
             *(dest+i)=*(src+i);         
         }
         *(dest+i)='\0';
         return dest;
     }

1.14 函数指针

本质上是一个指针,用来指向函数的地址

格式:数据类型 (*指针变量名)(参数列表)

函数名表示函数的首地址,函数是没有办法计算字节

void sum()                void (*p)()
void sum(int a,float b)   void (*p)(int a,float b) 
int sum()                 int (*p)()
int sum(int a,double b)   int (*p)(int a,double b)

#include <string.h>
#include <stdlib.h>

void Sum()
{
    int a=100,b=10;
    printf("a+b=%d\n",a+b);
}
int main(int argc, const char *argv[])
{
    Sum();//0x10   直接使用函数的地址调用函数
    (*Sum)();      //通过地址存储的值进行调用函数
    (*******Sum)();
    printf("SUm=%p\n",Sum);

//    printf("sizeof(SUm)=%ld\n",sizeof(Sum));
    printf("*Sum=%p\n",*Sum);
    printf("**Sum=%p\n",**Sum);
    printf("*****Sum=%p\n",*****Sum);
    void (*p)()=Sum;//p=Sum

    p();//通过函数指针调用函数
    (*p)();//通过函数指针指向地址对应的值调用函数
    return 0;
}

1.15 函数指针数组

本质上是一个数组,存储多个函数指针

格式: 数据类型 (*数组名[常量表达式])(参数列表)

#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;
 //定义一个    
 double a;
 int *p=&a;
    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.16 多级指针

一级指针存储变量的地址

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

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

....

定义格式: 存储类型 数据类型 ****指针变量名 【注意*个数不限】

注意:无论是几级指针,都是指针,指针在64位操作系统占8字节,32位占4字节

int main(int argc, const char *argv[])
{
    int a=100;
    int *p=&a;
    int **q=&p;
    int ***m=&q;
    printf("p=%ld  q=%ld  m=%ld\n",sizeof(p),sizeof(q),sizeof(m));

    printf("a=%d  *p=%d  **q=%d  ***m=%d\n",a,*p,**q,***m);
    printf("&a=%p  p=%p  *q=%p   **m=%p\n",&a,p,*q,**m);
    
    return 0;
}

 

1.17 通用类型指针

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

格式: void *指针变量名

int a=100;
void *p=&a;
printf("*p=%d\n",*(int *)p);
int arr[3]
memset(arr,0,sizeof(arr));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ck钉钉钉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值