C语言指针详解

C语言指针详解

// 举例说明:
// 代码:
#include<stdio.h>
int main() {
	// 定义一个指针变量(没有赋值):
	int *p;  // '*' 是指针变量的标识符!表明某一变量是指针变量。
	// 定义一个整型数组变量:
	int array[]= {5,10,15};
	// 指针变量的赋值只能用同类型的变量的地址进行赋值:
	p=array;   // 数组名,就是数组的第一个元素所在的地址! 即array==&array[0]
	
	printf("已知条件: int *p;     array[]= {5,10,15};     p=array;\n\n");
	
	// 输出指针p的地址。
	printf("&p \t\t: %d\n",&p);

	// 输出指针p所保存的地址,因为指针变量,存储的是某一变量的地址!
	printf("p \t\t: %d\n",p);

	// 输出数组array的地址。
	printf("array \t\t: %d\n",array);

	// 输出数组array第一个元素的地址,注意由于array[0]的类型为整型,所以获取地址要加取址符'&'
	printf("&array[0] \t: %d\n",&array[0]);
	
	// 输出数组array第二个元素的地址。
	printf("&array[1] \t: %d\n",&array[1]);
	
	// 输出指针p所指向的元素的值!'*' 该符号表示获取内存地址中所存储的值!
	printf("*p \t\t: %d\n",*p);
	
	// 输出数组array的地址中所保存的值!
	printf("*array \t\t: %d\n",*array);

	// 输出数组array第二个元素的地址中所保存的值!
	printf("*(&array[1]) \t: %d\n",*(&array[1]));
	
	// 输出指针地址自增一后的地址!
	printf("++p \t\t: %d\n",++p);
	
	// 输出指针p所指向的元素的值!'*' 该符号表示获取内存地址中所存储的值!
	printf("*p \t\t: %d\n",*p); // 由于p中的地址自增一,因此此时p指向数组第二个元素 

	// 输出指针地址自增一后的地址中所存放的值!
	printf("*(++p) \t\t: %d\n",*(++p)); // 先是p是中的地址自增一,然后再是去地址中存放的值 

	// 输出数组array第三个元素值!
	printf("array[2] \t: %d\n",array[2]);

	return 0;
}

输出结果:
在这里插入图片描述
注意事项:

  • 指针地址的类型为长整型,因此有的编译器运行上述代码时,对于"%d"可能会报错,需要改成"%ld"。
  • const char *p=“Hello world!” 是可行的,因为常量字符串的赋值给指针变量时,赋值的值其实是字符串变量的首地址,而非字符串变量本身!
  • const int *p=5 是不可行的,因为整型变量的赋值,赋值的值本身不是地址,而是整型变量的值!
  • 其他注意事项如下图所示:
    在这里插入图片描述
    输出结果:
    在这里插入图片描述

其他:

  • 01、通过指针来读取数据
#include <stdio.h>
int main() {
	int  x;
	int *px = &x;
	scanf("%d",px);
	printf("%d",x);
	
	return 0;
}

在这里插入图片描述

  • 02、如果指针不指向任何有意义的内存地址或变量,赋值为NULL
int *q = NULL;
  • 03、*和&互为相反即:(*&x)就是x。
  • 04、通过强制类型转换完成不同类型指针间的相互赋值
int a;char b;
int *pa;char *pb;
pa=(int*)&b;
pb=(char*)pa;
  • 05、用sizeof()获取变量占据的内存单元数
float array[20];
printf("%d\n",sizeof(array)); //将输出4*20=80
  • 06、对于数组a来说,a 和 &a[0] 的值相同,都是数组0号元素地址,*a 等同于a[0],&a是数组地址,值和上两者一样,但意义不同!
  • 07、对于指向数组a的指针p来说,可以通过*(p+2)或者p[2]来访问数组a的第三元素,如:
#include <stdio.h>
int main() {
	int a[5]={1,2,3,4,5};
	int *p=a;
	printf("*(p+2): %d\n",*(p+2));
	printf("p[2]: %d\n",p[2]);
	return 0;
}

在这里插入图片描述

  • 08、元素地址 = 数组起始地址 + sizeof(element)*元素下标index
  • 09、对与指针p±n而言,实际上加减的值不是n,而是n * (sizeof (element))
  • 10、数组名为常量指针不可对其进行赋值或修改,但可用于加减操作。如:
int a[10]={};//a为整型数组
int *p = a;
/*
 *(a + n)、a[n]*(p+n)、p[n] 完全相同

a++是错误的,因为a为常量指针
p++是正确的,因为p不是常量指针
*/
  • 11、如果指针p指向数组a的第3个元素,则p[-1]的值为数组a的第2个元素的值,如:
#include <stdio.h>
int main() {
	int a[5]={1,2,3,4,5};
	int *p=&a[2];
	printf("p[-1]: %d\n",p[-1]);
	return 0;
}

在这里插入图片描述

  • 12、二维数组中指针的应用
/*
table包含31维数组
table表示0号数组的地址
*(table+i)表示第i号数组
**(table+i)表示第i号数组的首个元素
*(*(table+i)+j)表示i号一维数组中下标为j的元素
*/
#include <stdio.h>
int main() {
	int table[3][2]={{1,2},{3,4},{5,6}};
	printf("%d\n",**(table+1));
	printf("%d\n",*(*(table+1)+1));
	return 0;
}

在这里插入图片描述

  • 13、const在指针中的应用及含义
const限定符告诉编译器被限定的变量的值不可修改,
用于限定修改权限,常用于变量定义和形参定义

从右向左理解
1.const char *sPtr; 指针sPtr 指向字符常量
*sPtr='a';引起编译器报错,不允许sPtr对指向对象值的修改

2.int *const ptr=&x;ptr是常量指针,指向整型变量x
*ptr =7;正确
ptr=&y;错误,常量指针不能重新其指向其它对象

3.const int *const ptr=&x;兼具以上两点
*ptr =7;错误
ptr=&y;错误
  • 14、指向指针的指针
// 代码举例:
#include <stdio.h>
int main() {
	int a;
	int *p;
	int **q;
	
	a=25;
	p=&a;
	q=&p;
	
	printf("a=%d\n",a);
	printf("*p=%d\n",*p);
	printf("**q=%d\n",**q);
	
	return 0;
}

在这里插入图片描述

  • 15、C语言中指针做函数参数传递二维数组有两种基本方法:

1、传递"数组指针",代码举例:

#include<stdio.h>
void output(int(*pa)[3],int n);
int main() {
	int a[2][3]= {
		{1,2,3},
		{4,5,6}
	};
	output(a,2);
	return 0;
}
void output(int(*pa)[3],int n) { //这个函数只能输出n行3列的二维数组
	int i,j;
	for(i=0; i<n; i++) {
		for(j=0; j<3; j++)
			printf("%d ",pa[i][j]);
		printf("\n");
	}
}

在这里插入图片描述
2、传递"指针数组",即:先将数组的行指针存储到一个指针数组中,再将指针数组传递到子函数中去。代码举例:

#include<stdio.h>
void output(int *pa[],int row,int col);
int main() {
	int a[2][3]= {
		{1,2,3},
		{4,5,6}
	};
	int  i;
	int *pa[2];
	for(i=0; i<2; i++ )
		pa[i]=a[i];
	output(pa,2,3);
	return 0;
}
void output(int *pa[],int row,int col) { //这个函数更通用,但调用前,要做好准备工作。
	int i,j;
	for(i=0; i<row; i++ ) {
		for(j=0; j<col; j++ )
			printf("%d ", pa[i][j] );
		printf("\n");
	}
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

☜lgl☞

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

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

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

打赏作者

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

抵扣说明:

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

余额充值