C语言的灵魂-指针
2019-03-16 本文已影响0人
大鱼鱼
const指针:
int const *p1;
int *const p2 ;
const int * const ;
- const在 * 的左边:修饰的是指针指向的内存;
1.指针可以改变指向。
2.不可以通过指针改变其所指内存的值。 - const在*号的右边:修饰的是指针变量本身;
1.指针不可以改变指向。
2.可以通过指针改变其所指向内存的值。 - *两边都有const:
1.指针不可以改变指向。
2.不可以通过指针改变其所指内存的值。
注意:变量本身仍可以通过变量名去修改。
字符串指针和字符串数组
1.char str[10];
2.char *str1="Beijing";
3.char *str1=str;
第二条语句代表一个char型指针str1指向字符串“Beijing”的首地址;
在这条语句中只能对字符串进行读取,即指针指向字符串常量时,只能访问元素而不能对其中的元素进行改变。因为指针的本质是一个地址,并没有为修改后的数据开辟存放的空间,所以如果要修改元素,则需要定义一个字符数组且为其开辟足够大的内存,使指针指向数组的地址。
如1,2,3条语句所示。
函数和函数指针
- int (*p)(int a):指向返回值为int,参数值为int a的函数指针。
- int *p(int a):指向返回值为int,参数值为int a的函数。
二维数组指针访问二维数组
int array[2][3]={{1,2,3},{4,5,6}};
int (*p)[2][3]=NULL;p=&array;
- p[0][0]=array[0]==*(p[0]+0)
- p[0][1]=array[1]==*(p[0]+1)
- p+1:跨过6*4个字节(跨过一整个数组)
- p[0]+1: 跨过3*4个字节(跨过一行)
- p[0][0]+1:跨过4个字节(跨过一行中的一个数据元素)
多维指针
- 二维指针:如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
int a;
int *p=&a;
int **p1=&p;
- 定义整形变量a
int a=10;
int *p=&a;
int **p1=&p;
printf("a=%d p=%p p1=%p\n",a,p,p1);
printf("*p=%d *p1=%p\n",*p,*p1);
数组指针
- 指向数组的指针
- 定义方式:类型名称(*指针名)[数组长度]
例如:
int a[5]={1,2,3,4,5};
int(*p)[5]=&a;
- 定义时不能丢掉括号,因为[ ]优先级比*高,如果丢掉括号,会成为指针数组。
- 数组指针定义时的数组长度,元素类型 ,必须与指向的数组给出的长度,类型相同。
int (*p)[5]
指向数组长度为5的整形数组的指针。
char* (*p1)[10]
指向数组类型为char*[10]的数组指针。
int *p2[10]
一个数组 类型为int *[10] - 数组指针指向的是整个数组,而不是数组元素,所以指针运算p+1,相当于p+1*siaeof(数组名)越过整个数组
- 访问数组元素的方式:a[0],a,(a+1),(*p)[0],p[0][0],p[0][1]
int (*p)[5];
int array[5]={1,2,3,4,5};
p=&array;
array[0]
- (array+0)==* array
- p==array
p[0]==array
( * p)[0]=p[0][0]
如果通过*(p+1)来访问数组元素时,p+1一定是已经越过了整个数组,出现越界。
指针数组
- 一组类型相同的有序集合,如果数组元素都是指针变量,就称它为指针数组。
char* pArray[3]={0};
char arrChar1[]="how";
char arrArray2[]="are";
char * str="you";
pArray[0]=arrChar1;
pArray[1]=arrAarray2;
pArray[2]=str;
for(int i=0;i<3;i++){
printf("%s\n",pArr[i]);}