一、指针
1.地址
内存单元的编号叫地址;
2.指针
内存单元的地址叫指针;
变量的地址叫指针;
3.指针变量
存储变量地址的变量叫指针变量;
说明:
在不作区分的情况下,将地址 指针 指针变量统称指针;
4.指针变量的形式
存储类型 数据类型 *指针变量名;
eg:
int *p;
说明:
存储类型:同普通变量,指针变量本身的存储类型;
数据类型:既可以是基本类型,也可以是struct,也可以是void,还可以是指针;
此数据类型是指针指向空间内容的数据类型;(重点)
*:表示变量为指针变量;
指针变量名:符合命名规则;
5.指针变量的初始化
存储类型 数据类型 *指针变量名 = 地址值;
eg1:
int i = 10;
int *p = &i;//由于p指针指向的数据为int 型,所以需要给指针变量p赋int型变量的地址;
eg2:
char ch = 'a';
char *q = &ch;
6.& 与 *
&:取变量的地址
*:
1> 在定义指针变量时,*用来说明定义的变量为指针变量;
eg:
float *p;//*说明定义的变量p为指针变量;
2> 在定义之后,指针变量名前加*,含义是取指针指向空间的值;(解引用)
eg:
int i = 10;
int *p;
p = &i;//给指针变量p赋i的地址
printf("i=%d *p=%d\n",i, *p);
注意:
& 与 *互为逆运算;
eg:
int i = 10;
printf("%d\n",*(&i));//结果10
7.指针的运算
本质:地址的运算
定义指针变量 px和py;
1> 算数运算:(+ - ++ --)
px+n:指针向地址大的方向偏移n个数据类型;(此数据类型为指针指向内容的数据类型)
px-n:指针向地址小的方向偏移n个数据类型;(此数据类型为指针指向内容的数据类型)
px++://等价:px=px+1;指针向地址大的方向移动1个数据类型;(此数据类型为指针指向内容的数据类型)
px--:指针向地址小的方向移动1个数据类型;(此数据类型为指针指向内容的数据类型)
px-py:两指针之间相差的数据类型的个数;
eg:
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &a[0];//
int *q = &a[7];
printf("p=%p p+3=%p\n",p,p+3);//p=0xbffb8334 p+3=0xbffb8340
printf("q=%p q-3=%p\n",q,q-3);//q=0xbffb8350 q-3=0xbffb8344
printf("q-p=%d\n",q-p);//q-p=7
注意:
n为整数
2> 关系运算(> < >= <= == !=)
eg1:
int *p;//"野指针"
*p = 10;//不允许通过野指针访问野指针指向的空间;
eg2:
int *p = NULL;//stdio.h定义的宏值 #define NULL 0
if(NULL == p)//判断指针是否为有效的指针
{
return ;
}
*p = 10;//ERROR
3> 赋值运算
eg1:
int i = 10;
int *p = &i;
eg2:
int i = 10;
int *p = &i;
int *q = p;
eg3:
int a[10];
int *p = a;
二、指针与数组
通过指针操作数组;
1、一级指针与一维数组
eg:
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = a;//int *p = &a[0];
int i;
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
for(i=0;i<10;i++)
printf("%d ",p[i]);
printf("\n");
结论:
1> 数组中第i个元素的表示:(i=0,1,2,.....)
a[i] p[i] *(a+i) *(p+i) *(&a[i]) *(&p[i])
2> 数组中第i个元素的地址的表示:(i=0,1,2,.....)
&a[i] &p[i] (a+i) (p+i)
三、字符指针
1.形式
存储类型 char *指针变量名;
eg1:
char ch = 'a';
char *p = &ch;//
*p = 'b';
printf("*p=%c\n",*p);
eg2:字符指针操作字符串(重点)
char *p = "hello world";//将字符串的首地址赋给p指针
printf("*p=%c\n",*p);//*p='h'
*p = 'a';//ERROR 不能通过指针修改常量区的东西
例子:
char *p;
p="hello world";
printf("*p=%c\n",*p);//*p='h'
printf("p=%s\n",p);//p=hello world
printf("*p=%p\n",*p);//p=0x80484f0"字符串首地址"
eg3:字符指针的赋值
char *p = NULL;
p = "hello world";
eg4:
char ch[20] = "hello world";(√)
char ch1[20];
ch1 = "hello world";(×)//数组名不能作为左值
eg5:
char ch1[20];
ch1[20] = "hello world";(×)//ch1[20]表示的是数组ch1中的第21个元素,越界
eg6:
char ch[20] = "hello world";//将常量区的"hello world"拷贝一份到ch的空间
*ch = 'a';
printf("%s\n",ch);//结果:aello world
实例:
1、求一个字符串的长度。(指针)
#include<stdio.h>
int main()
{
char ch[64];
gets(ch);
int num=0;
char *p = ch;
while(*p != '\0')
{
num++;
p++;
}
printf("num=%d\n",num);
return 0;
}
2、计算一个字符串的空格数,并删除全部空格;
#include<stdio.h>
int main()
{
char a[64];
gets(a);
int i,j,num=0;
for(i=0;a[i]!='\0';i++)
{
if(a[i] == ' ')
{
num++;
for(j=i;a[j]!='\0';j++)
a[j] = a[j+1];
i--;
}
}
printf("num=%d %s\n",num, a);
return 0;
}
3、用指针给一个数组赋值,并打印。
#include<stdio.h>
int main()
{
int a[10];
int len = sizeof(a) / sizeof(int);
int *p = a;
int i;
for(i=0;i<len;i++)
scanf("%d",p++);
p = a;
for(i=0;i<len;i++)
printf("%d ",p[i]);
printf("\n");
return 0;
}