C基础day10(2023.7.12)

一、Xmind整理:

 

二、课上练习:

 练习1:二维数组和指针(打印地址和值)

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;
}

 练习2:自定义函数,计算二维数组的和,要求使用数组指针做参数 

int Sum(int line,int row,int (*p)[row])
{
    int sum=0;
    for(int i=0;i<2;i++)
    {
    for(int j=0;j<3;j++)
    {
        //sum+=p[i][j];
        sum+=*(*(p+i)+j);
    }
    }
    return sum;
}
int main(int argc, const char *argv[])
{
    int arr[][3]={11,33,5,6,7};
    int line=sizeof(arr)/sizeof(arr[0]);
    int row=sizeof(arr[0])/sizeof(arr[0][0]);
    int s=Sum(line,row,arr);
    printf("s=%d\n",s);
    return 0;
}

 练习3: 自定义函数,计算第二大值并返回,要求使用数组指针做参数

 思路:计算最大值以及最大值下表 计算第二大值,如果下表等于第一大值行列下表,   则跳过, 否则进行计算第二大值

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Second_Max(int line,int row,int(*p)[row])
{
	int maxi,maxj,second;
	for(int i=0;i<line;i++)
	{
		for(int j=0;j<row;j++)
		{
			if(i==0&&j==0)
			{
				maxi=i;
				maxj=j;
			}
			if(*(*(p+maxi)+maxj)<*(*(p+i)+j))
			{	
				maxi=i;
				maxj=j;
			}
		}
	}	
	for(int i=0;i<line;i++)
	{
		for(int j=0;j<row;j++)
		{
			if(i==maxi&&j==maxj)
				continue;
			if(i==0&&j==0)
				second=*(*(p+i)+j);
			if(second<*(*(p+i)+j))
				second=*(*(p+i)+j);
		}
	}
	return second;
}
int main(int argc, const char *argv[])
{
	int arr[][3]={11,22,33,44,55,66};
	int line=sizeof(arr)/sizeof(arr[0]);
	int row=sizeof(arr[0])/sizeof(arr[0][0]);
	int n=Second_Max(line,row,arr);
    printf("第二大的值为:%d\n",n);
	return 0;
}

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

void YangHui(int (*p)[6],int line)
{
	int i,j;
	for(i=0;i<line;i++)
	{
		for(j=0;j<=i;j++)
		{
			if(j==0 || i==j)
			{
				*(*(p+i)+j)=1;
			}
			else
			{
			//	a[i][j]=a[i-1][j]+a[i-1][j-1];
				*(*(p+i)+j)=*(*(p+i-1)+j)+	*(*(p+i-1)+j-1);
			}
			printf("%d\t",*(*(p+i)+j));
		}
		printf("\n");
	}
}
int main(int argc, const char *argv[])
{
	int arr[6][6];
	int line=sizeof(arr)/sizeof(arr[0]);
	YangHui(arr,line);
 }

 练习5:指针数组 

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;
}

 练习6:字符指针数组存储多个字符数组的地址 

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));
    }

 练习7:字符指针数组存储多个字符串常量的地址

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));
    }

 练习8: 在终端输入,使用字符指针数组

 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

 练习9:指针函数

需求:
/*返回局部变量的地址:段错误    
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;
}

 练习10:字符串拷贝,返回拷贝后的地址

 char *strcpy(char *dest,  char *src)
     {
         int i;
         for(i=0;*(src+i)!='\0';i++)
         {
             *(dest+i)=*(src+i);         
         }
         *(dest+i)='\0';
         return dest;
     }

 练习11: 函数指针

#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;
}

  练习12:函数指针数组

#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;
}

 练习13 :多级指针

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;
}

  练习14:通用类型指针

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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值