#8:C语言复习:指针基础;

本文详细介绍了C语言中的指针基础,包括指针变量的定义、赋值,以及如何通过指针引用变量。同时,文章讨论了指针与数组的关系,特别是对于一维和二维数组,阐述了各种地址表达式和元素访问方式,并提供了相关示例来说明指针算术和关系运算的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

指针变量

                    指针变量的定义形式:

                            基类型    *指针变量名1,*指针变量名2,…;

                            指针变量只能指向由定义时基类型规定的类型变量,不能指向其他的变量

                    指针变量的赋值

                            在定义的同时进行初始化
                            int i;
                            int *p=&i;            &取地址计算符,&i表示i的地址。

指针变量的引用

void main()
{
	int a,b,c;
	int *p;
	a=5;
	b=a+3;
	p=&a;			//	通过&把a的地址赋给了p;

	c=*p+3;			//	通过指针运算符*把p指向的变量a的值输出,在进行运算;间接访问。
	printf("%d,%d\n",a,b);
	printf("%d,%d\n",*p,c);
}

例:

输入a,b两个整数,用指针实现先大后小的顺序输出:

void main()
{
	int *p1,*p2,*p,a,b;
	scanf("%d%d",&a,&b);					
        p1=&a;			//	给指针赋值地址的时候,不加*;* 表示取地址中的内容; 
	p2=&b;

	if(a<b)			//	通过交换指针来改变输出的最大最小值,而原数值没变;
	{
		p=p1;
		p1=p2;
		p2=p;
	}

	printf("a=%d,b=%d\n",a,b);	//	输出的a,b并没有变化;

	printf("max=%d,min=%d\n",*p1,*p2);		//	但是指针变化,所以输出变化;
}

以上仅仅改变指针所指的地址,而原地址中的内容并未发生变化!


指针与数组:

一维数组:


                                数组名是0号元素的地址,是常量,不能赋值

                                1.    指向数组元素的指针:

                            指针p既可以指向整型变量(数组名本身即为arr[ 0 ]地址,不需要加&),

                                     也可以指向整形数组的元素( 元素需要加&以取地址 ):

                                p=&a[0];
                                p=a;
                                int *p=&a[0]
                                int *p=a;


引用一个数组元素的两种方法:

                                1.    指针法:有*(a+i)和*(p+i)两种形式,都是用间接方式来访问的;
        
                                2.    下标法:有a[i]和p[i]两种形式;

例:

用下标法和指针法分别输出数组的全部元素:

void main()
{
	int a[10],i,*p;
	for(i=0;	i<10;	i++)
		scanf("%d",&a[i]);

	for(i=0;	i<10;	i++)			//	指针法之	*(a+i)形式			一定从a的开头输出
		printf("%d",*(a+i));

	printf("\n");
	for(p=a;	p<(a+10);	p++)		//	指针法之	*p形式				输出的是指针p指定后面的数据,不一定从头输出
		printf("%d",*p);

	printf("\n");
	for(i=0;	i<10;	i++)			//	下标法之	a[i]形式			从第i个变量开始,(从零开始)
		printf("%d",a[i]);

	printf("\n");
	for(p=a,i=0;	i<10;	i++)			//	下标法之	p[i]形式			同上
		printf("%d",p[i]);
	printf("\n");

}

说明:


                                        指针可以实现本身值得改变,数组名则不行。即p++是合法的,但是a++就不可以;

                                        在输出时要注意指针的指向需要归零:

例:

void main()
{
	int *p,i,a[5];				
	p = a;
	for(i=0;	i<5;	i++)
		scanf("%d",p++);		//	在此时,p指向的是最后一位
	
//	p = a;					//	应添加归零:	p=a;
										
	for(i=0;	i<5;	i++,p++)	//	未归零直接指针向后移,无法输出正确的值;
		printf("a[%d]=%d\n",i,*p);
}

指针的算术运算和关系运算:


                               1.    指针的算术运算只有在指针指向一串连续变量的存储单元的时候,指针的运算才有意义,

                                        若假定p已经指向a:

                                        1.    计算*p++时,结合方式由右向左,等价于*(i++),即先计算*p,再p++

                                        2.    *(++p)和*(p++)不同。

                                        3.    (*p)++    表示p所指的元素值+1,即p=a[0]+1;

                                        4.    基类型相同的两个指针可以相减,但不能相加。

                                       若指针p1,p2都指向a中的元素,但p2在p1后面,则p2-p1就是p1与p2之间的元素个数;

指针的关系运算:


                                只有基类型相同,且指针指向同一串连续的存储单元的时候,才可以比较(地址值)

                                    int a[5],*p1,*p2,*p3;    
                                    p1=&a[1];
                                    p2=&a[4];

                                    则    p1<p2 为真。

                                if (p3=='\0')    printf("p3 points to Null.\n");也是正确的;

指针与二维数组


                            二维数组可以看成一维数组,每个一维数组中的元素,又是一个一维数组;

                            二维数组a[i][j]的地址:

                    1.    &a[i][j]                    //    最通常的输出
                        
                    2.    a[i]+j                      //    二维数组中的    a[i]表示的是第i行(从零开始)的首个元素的地址;
                    
                    3.    *(a+i)+j                  //    同上

                    4.    &a[0][0]+4*i+j        //    在第i行前有4*i+j个元素存在(列数为4),即按个数输出

                    5.    a[0]+4*i+j              //    同上;            


二维数组各类地址及用地址引用元素的各种不同表示形式



                a                                二维数组名,指向一维数组a[0],即第0行首地址            行地址
                
                a[0],*(a+0),*a                    第0行第0列元素地址,即a[0][0]的地址                    行地址

                a+1,&a[1]                        第一行首地址,指向一维数组a[1]                              行地址

                a[1],*(a+1)                        第一行第零列元素地址,即a[1][0]的地址                 行地址

                a[1]+2,*(a+1)+2,&a[1][2]        第一行第二列元素a[1][2]的地址                          元素地址

                *(a[1]+2),*(*(a+1)+2),a[1][2]    第一行第二列元素a[1][2]的值                            元素地址

例:

输出二维数组有关的值:

void main()
{
	int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
		printf("%X,%X,%X,%X,%X\n",a,*a,a[0],&a[0],&a[0][0]);
	//	依次输出第零行首地址,a[0][0]的地址,a[0][0]的地址,第0行首地址,a[0][0]的地址;
		printf("%d,%d,%d\n",a[1][1],*(a[1]+1),*(*(a+1)+1));
	//	输出数组元素a[1][1]的值
}



指向二维数组元素的指针:


与指向普通变量的指针变量相似;


例:

输出二维数组的元素:

void main()
{
	int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	int *p;

	for(p=a[0];	p<a[0]+12;	p++)			//	用指针进行输出;
	{

		if(	(p-a[0])%4==0)	printf("\n");		//	每行输出4个元素;

		printf("%4d",*p);
	
	}
	printf("\n");
}

指向二维数组行的指针变量


                                                                             int a[3][4];
                                                                             (*p)[4];
                                                                             p=a;

                                                        p所指向的是包含4个int型,元素的一维数组
                                                                          圆括号不能少;

输出二维数组的元素(用二维数组行的指针):

void main()
{
	int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	int (*p)[4];					//	指向含有4个int型元素的一维数组;
	int i,j;
	p=a;

	for(i=0;	i<3;	i++)
	{
		for(j=0;	j<4;	j++)
			printf("%3d  ",*(*(p+i)+j));	//	标准化二维数组的行输出方式;!!!!!
		printf("\n");
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值