指针与数组

一,指针

1.1指针和一维数组

int *p=NULL;

&arr[0]=arr;

p=arr;

&arr:整个数组的首地址,偏移量为整个数组的大小

值得等价关系:   arr[i]   <====> *(arr+i)<====> p[i] <====>*(p+i) <====>*p++

地址的等价关系:&arr[i]   <====>arr+i<====>&p[i]<=====>p+i

#include <stdio.h>
int main(int argc,const char *argv[])
{  
	int a[5]={1,2,3,4,5};
	int *p=&a+1;//数组的首地址 偏移一个数组
	printf("%d %d",*(a+1),*(p-1));//结果:2 5 
		return 0;
}

补充:

1.2 指针和一维字符数组

char str[]="hello";

printf("%s",str);

1> 指针指向一维字符数组的首地址【可以通过指针修改数组的内容】

                char str[]="hello";

                char *p =str;//p==str

                scanf("%s",str);

                scanf("%s",p);

2>指针直接指向字符串的首地址【不可以通过指针修改字符串的内容】

                     char *p="hello";

                     *(p+1)=‘k’//错误,字符串常量在.ro段

                     char str[]="hello";//注意:数组长度在输入时防止越界
    

                      char *p=str;//p==str
                      char *p1="hello";
                      printf("str=%p,p=%p,p1=%p\n",str,p,p1);//p和str的地址相同(字符串复印件的地址),p1指的是.ro段的地址


 

1.3 指针和二维数组

        int arr[3][4]:

        &arr[0][0]:第一行第一列元素的地址

        arr[0]:等价于一维数组arr的数组名,偏移的列(一个)

        &arr[0]:等价于一维数组数组名去地址,偏移的一整行

        &arr:偏移整个二维数组

          arr:表示偏移的一整行

int a[2][3]={1,2,3,4,5,6};
	//列偏移
	printf("&a[0][0]=%p\n&a[0][0]+1=%p\n",&a[0][0],&a[0][0]+1);
	printf("a[0]=%p\na[0]+1=%p\n",a[0],a[0]+1);
	//行偏移
	printf("&a[0]=%p\n&a[0]+1=%p\n",&a[0],&a[0]+1);
	printf("a=%p\na+1=%p\n",a,a+1);
	//整个数组偏移
	printf("&a=%p\n&a+1=%p\n",&a,&a+1);

地址等价:&arr[i][j]====>>*(arr+i)+j====>>arr[i]+j

值的等价:arr[i][j]====>>*(*(arr+i)+j)====>>*(arr[i]+j)

1.3.1 指针和二维数组结合

1.4 数组指针

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

定义格式:数据类型(*指针变量名)[常量表达式]            等价于二维数组数组名arr

数据类型:基本数据类型[int float char..],构造数据类型[结构体],指针类型,void

指针变量名:满足命名规范

(  )  [  ]:不可以省略

常量表达式:二维数组的列数

int arr[line][row];

1.用指针数组求最大值和第二大的值

#include <stdio.h>
int main(int argc,const char *argv[])
{  
	int a[2][3]={11,22,33,44,55,66};
	int (*p)[3]=a;//数组指针:指向二维数组地址指针
	int i,j,max=**p,sec=**p;
	for(i=0;i<2;i++)
	{
		for(j=0;j<3;j++)
			if(*(*(p+i)+j)>max)
			{
				max=*(*(p+i)+j);
			}
	}
	for(i=0;i<2;i++)
	{
		for(j=0;j<3;j++)
			if(*(*(p+i)+j)>sec&&(*(*(p+i)+j))<max)
			{
				sec=*(*(p+i)+j);
			}
	}
	printf("max=%d\nsec=%d\n",max,sec);

	return 0;
}

1.5指针数组

本质上是一个数组,表示存储多个指针,满足数组的使用方式

定义格式:数据类型 *数组名[常量表达式]          突出是一个指针数组 [ ]>*

常量表达式:表示指针的个数

int  a,b,c,d,e;

int *p=&a;int *p1=&b;int *p2=&c;...

 

指针数组存放变量地址

int *q[5]={&a,&b,&c,&d,&e};

指针数组存放数组地址

int *s[3]={str1, str2 ,str3};

int str1[] ,str2[] ,str3[];

指针数组表示字符串常量

char *str[3]={"hello","sdja","sdas"};

for(int i=0;i<3;i++)

printf("%s\n",str[i]);

1.6  多级指针

定义格式:数据类型 **指针变量名

注意:*的个数不限

1.7  void和指针

定义格式:void * 指针变量名

通用类型指针,它可以指向任何一种类型的地址,可以指向任何一种空间

在使用时,必须要进行强制转换

#include <stdio.h>
int main(int argc,const char *argv[])
{  
	int a=11;
	float b=1.1;
	char c='a';
	void *p=&a;
	printf("%d\n",*(int *)p);
	p=&b;
	printf("%f\n",*(float *)p);
	p=&c;
	printf("%c\n",*(char *)p);
	return 0;
}

1.8 const和指针

1>const 修饰的变量不可以改变值 

2>const 修饰的全局变量在.ro段

3>const修饰的局部变量在栈区

4>const和指针

        const int *p:*在const右边,const修饰的是值,值不能变,地址可以改变

        int const *p:*在const右边,const修饰的是值,值不能变,地址可以改变

        int * const p:*在const左边,const修饰的是地址,值能变,地址不可以改变

        const int *const p:const修饰的是值和地址,值不能变,地址也不可以改变

argc:命令行输入参数的个数

argv:指针数组,接受命令行输入的字符串

作业:

练习1:使用指针实现两个字符串的比较

#include <stdio.h>
int main(int argc,const char *argv[])
{  
	char arr[]="Jrc";
	char brr[]="JrcLAICAILAI";
	char *p=arr;
	char *p1=brr;
	int ret;
    while(arr)
	{
		if(*p==*p1)
		{
			p++;
			p1++;
		}else
		{
		break;
		}
	}
	ret=*p-*p1;
	printf("%d\n",ret);
	return 0;
}

2.使用指针实现字符串连接

#include <stdio.h>
#include <string.h>
int main(int argc,const char *argv[])
{  
	char arr[100]="Jrc";
	char brr[]=" handsome";
	char *p=arr;char *p1=brr;
	int len=strlen(arr);
	p=p+len;
	while(*p1)
	{
     *p=*p1;
	  p++;
	  p1++;

	}
    *p='\0';
	p=arr;

	printf("%s",p);
	return 0;
}

3.使用指针实现转置

#include <stdio.h>
#include <string.h>
int main(int argc,const char *argv[])
{  
	char str[]="shuaige JRC";
	char *head=str;
	char *tail=str;
	char temp;
	while(*tail)
		tail++;
	    tail--;
	while(tail>head)
	{
		temp=*tail;
		*tail=*head;
		*head=temp;
		head++;
		tail--;

	}
	printf("%s\n",str);
		return 0;
}

4.实现杨辉三角:

#include <stdio.h>
int main(int argc,const char *argv[])
{  
	int a[10][10],i,j;
	int (*p)[10]=a;
	for(i=0;i<10;i++)
	{
		for(j=0;j<10;j++)
			if(j==0||i==j)
			{
			*(*(p+i)+j)=1;	
			}else
			{
				*(*(p+i)+j)=0;
			}
	}
	for(i=1;i<10;i++)
	{
		for(j=1;j<i;j++)
			*(*(p+i)+j)=*(*(p+i-1)+j)+*(*(p+i-1)+j-1);
			}
	for(i=0;i<10;i++)
	{
		for(j=0;j<=i;j++)
			printf("%d\t",*(*(p+i)+j));
		putchar('\n');
			}


	return 0;
}

5.通过数组指针实现二维数组转置

#include <stdio.h>
int main(int argc,const char *argv[])
{  
    int arr[2][3]={1,2,3,4,5,6};
    int brr[3][2];
    int (*p)[3]=arr;
    int (*p1)[2]=brr;
    int i,j;
    for(i=0;i<2;i++)
    {
        for(j=0;j<3;j++)
            *(*(p1+j)+i)=*(*(p+i)+j);
    }
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
            printf("%d\t",*(*(p1+i)+j));
        putchar('\n');
    }
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值