C语言中,内存单元的地址成为指针,专门用来存放地址的变量,有时对地址,指针和指针变量不区分,统称指针。
1、指针变量的说明:
一般形式:<存储类型> <数据类型> *<指针变量名>
char *pName;
int a;
指针的存储类型是指针变量本身存储类型
指针说明时指定的数据类型不是指针变量的数据类型,而是指针目标的数据类型,简称为指针的数据类型
指针在说明的同时,也可以被赋值,叫做指针的初始化
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a = 3;
int *pa;
pa= &a;
printf("%x %d %p",pa,*pa,a);
}
结果:
2、指针的赋值运算指得是通过赋值运算符指针变量送一个地址
向一个指针变量赋值时,送的值通常都是地址常量,不能是普通的整数(除了零以外)
1、把一个普通的变量的地址给一个具有同数据类型的指针
double x = 15,*px;
px = &x;
2、把一个已有地址值的指针变量赋给具有相同数据类型的另一个指针变量
float a,*px,*py;
px = &a;
py = px;
3、把一个数组的地址赋给具有相同数据类型的指针
int a[20], *pa;
pa = a //等价于 pa = &a[0]
3、 指针运算
指针运算是以指针变量所存放的低质量作为运算量而进行的运算
指针运算的实质是地址的运算
指针运算的种类有限,他只能进行赋值运算、算术运算和关系运算
不同数据类型的两个指针实行加减整数运算是没有意义的
| 运算符 | 计算形式 | 意义 |
| + | px+n | 指针向地址大的方向移动n个数据 |
| - | px-n | 指针向地址小的方向移动n个数据 |
| ++ | px++,++px | 指针向地址大的方向移动一个数据 |
| -- | px--,--px | 指针向地址小的方向移动一个数据 |
| . | px.py | 两个指针之间相隔数据元数的个数 |
px+n表示的实际位置的地址量是:
(px)+sizeof(px的类型)*n
px-n表示的实际位置的地址量是:
(px)-sizeof(px的类型)*n
实验:pa-3:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[5] ={1,2,3,4,5} ;
int *pa ,*pb,n;
pa= &a[4];
pb = pa - 3;
//pb=&a[3]; //指向特定的时候要加地址符
n = pb-pa;
printf("%d %d %d %d",pa,*pa,*pb,pb);
}
结果:打印的分别是a[4]的地址即pa,a[4]即*pa,向前移动了3个数据即a[1]=*pb=2,a[1]的地址。
![]()
实验:pa+2:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[5] ={1,2,3,4,5} ;
int *pa ,*pb,n;
pa= a; //实际是将a[0]赋值给了pa
pb = pa + 2;
//pb=&a[3]; //指向特定的时候要加地址符
n = pb-pa;
printf("%d %d %d %d",pa,*pa,*pb,pb);
}
结果:和上面同理,向后移动了2个数据。

4、指针数组
p=a是将a[0]的地址给p其中想访问别的数组元素就可以移动指针的位置,*pi进行取地址就可以。
实验: 使用字符数组反序存放
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[] ={1,2,3,4,5} ;
int b[]={0};
int *pa ,*pb,n,i,j;
n = sizeof(a)/sizeof(int);
pa = a; //实际是将a[0]赋值给了pa
pb = b;
for(i= 0;i<n;i++)
{
//printf("%d\n",pa[i]);
pb[j]=pa[n-i-1];
printf("%d",pb[j]);
}
}
结果:
5、指针和二维数组
二维数组名代表数组的起始地址,数组名加一,移动一行元素,因此二维数组名被称为行地址。
如果对a[i]进行加减则是只移动单个元素。

实验:使用行指针遍历二维数组中的每一个元素
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[3][2]={{1,2},{3,4},{5,6}};
int *p[2],i,n,k=0;
for(i=0;i<=2;i++)
{
p[i]=a[i];
n=*p[i]+*(p[i]+1);
//k=k+n;
printf("%d %d\n",*p[i],*(p[i]+1));
}
//printf("%d",k);
}
结果:

6、字符指针和字符串
char str[] = "Hello world";
char *p = str;
在c语言中,当一个字符指针指向一个字符串常量时,不能修改指针的对象的值。
char *p = "Hello world";
*p = 'h';
实验:使用两个字符串数组实现字符串函数的连接功能:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[3][2] ={{1,2},{3,4},{5,6}};
char ch[100]="welcome";
char *p="hello world";
int i=0;
while(ch[i]!='\0')
{
i++;
}
while(*p!='\0')
{
*(ch+i)=*p;
p++;
i++;
}
*(ch+i)=*p;
puts(ch);
puts(p);
}
7、 指针数组
double *pa2,a[2][3]
把一维数组a[0]和a[1]的首地址分别赋予指针变量数组的元数pa[0]和pa[1];
pa[0] = a[0]; //等价于pa[0] = &a[0][0]
pa[1] = a[1]; //等价于pa[1] = &a[1][0]
此时pa[0]指向了一维数组a[0]的第一个元素,而pa[1]指向了一维数组a[1]的第一个元素。
实验:将二级数组的所有的值进行求和
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int a[3][2]={{1,2},{3,4},{5,6}};
int *p[2],i,n,k=0;
//p[0]=a[0];
//p[1]=a[1];
//p[2]=a[2];
for(i=0;i<=2;i++)
{
p[i]=a[i];
n=*p[i]+*(p[i]+1);
k=k+n;
printf("%d %d\n",*p[i],*(p[i]+1));
}
printf("%d",k);
}
结果:

7、多级指针
多级指针的定义
7.1、多级指针的运算
#include<stdlib.h>
int main()
{
int i,n;
int *p[5]={1,2,3,4,5};
n=sizeof(p)/sizeof(char*);
int **pa;
pa=p;
printf("%p %p",*p,*pa+1);
}
结果:
![]()
7.2、 多级指针和指针数组
char *ps[5] = {"Beijing","Fuzhou","Xiamen","XiAn","ShangHai"};
实验:使用二级指针将指针数组里的元素全部输出:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int i,n;
char *p[5]={"Beijing","Fuzhou","Xiamen","XiAn","ShangHai"};
n=sizeof(p)/sizeof(char*);
char **pa;
pa=p;
while(i<n)
{
printf("%s\n",*(pa+i) );
i++;
}
}
结果:

8、void指针
一般形式为: void *<指针变量名称>;
对于void指针,在没有强制转换类型之前,不能进行任何指针的算术运算。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int n,i,*q;
int a[5]={1,2,3,4,5};
void *p;
p=a;
q=(int*)p;
n=sizeof(a)/sizeof(int);
for(i=0;i<n;i++)
{
printf("%d ",*(q+i));
}
}
结果:
![]()
9、const指针
const <数据类型 > 变量名 =[<表达式>];
9.1、常量化指针目标表达式
const <数据类型> *<指针变量名称> [= <指针运算表达式>];
常量化指针目标限制通过指针改变其目标的数值
但是指针变量存储的地址可以修改
9.2、常量化指针变量及其目标表达式
const <数据类型>* const <指针变量名> = <指针运算表达式>
常量化指针目标是限制通过指针改变其目标的数值
但是<指针变量>存储的地址值可以修改
9.3、常量化指针变量
一般说明形式
<数据类型> * const <指针变量名称> [<指针运算表达式>]
使得<指针变量>存储的地址值不能修改。
但可以通过*<指针变量名称> 可以修改所指向变量的数值。
1426

被折叠的 条评论
为什么被折叠?



