1、指针的算术元素
总结:
p + n:p+n对于p向地址增大的方向移动n个数据
实际的变化:p + sizeof(数据类型)*n
p - n:p-n对于p向地址减小的方向移动n个数据
实际的变化:p - sizeof(数据类型)*n
p++:p向地址增大的方向移动1个数据
实际的变化:p + sizeof(数据类型)
p--:p向地址减小的方向移动1个数据
实际的变化:p - sizeof(数据类型)
p - q(p和q的数据类型相同):这两个指针之间相差的数据的个数
实际变化:(p - q)/sizeof(数据类型)
注意:
(1)指针的算术运算只有在操作连续的内存空间的时候才有意义
(2)p是指针变量,以上这些方法也适用于指针常量,但是++、--除外
1.2 为什么使用数组名[下标]就可以访问数组中的元素
总结:
(1)数组名代表的是数组首元素的地址,地址常量,不能对它进行++、-- ,a的数据类型:int *
(2)数组名代表的是整个数组 sizeof(a)
1.3 通过指针常量来访问
#include <stdio.h>
void main()
{
int a[]={1,2,5,3,8,9,6};
int *p = a;
printf("p的起始地址:%d\n",p);//1703716
printf("*p++ = %d\n",*p++);//1
/*
*和++的优先级相同,运算顺序从右向左,所以*p++就相当于*(p++);
这里存在一个知识误区:本应该先执行括号内的p++,使p从指向a[0]变成指向a[1];
但其实事实并非如此;事实是,对于直接对*p++的输出来说,第一步是运算*p,输出后,第二步再运算p++;
需要注意的是:*和++对于p的运算,都是单独运算,比如第一步:*p就是对p所指向的地址进行取值,第二步:p++对于p所指向的地址+1个数据类型的字节数;
*/
printf("*p++后的地址:%d\n",p);//1703720
printf("*p的值是:%d\n",*p);//2
printf("a[0]=%d\na[1]=%d\n",a[0],a[1]);//1,2
}
*p++(先取值,再自加,地址自加,改变指针指向,所有指针常量不能自增)
p++ : p = p + 1
++是有赋值操作的,所以p的值会被改变
p+1
访问p的下一个地址,因为没有对p的赋值操作,所以p值不会被改变。
1.4 通过指针变量来访问
1.5 数组的访问
1.6 易错点
案例1
printf()是一个右结合,从右往左
案例2
形参都是当作指针来执行的
案例3
字符串常量不能被修改,但是可以被访问
1.7 指针的指向没有发生改变
1.8 指针的指向发生改变
案例
编写一子函数,实现字符串的链接
指针函数:指的是函数的返回值是一个指针,比如我的函数返回的是一个指向整数int的指针,定义格式如下:
int *p(int a,int b); //注意这里的*与P之间是没有括号的,所以含义是函数p(int,int)会返回一个(int *)指针
2、指针与二维数组
a+j=&a[j] -> *(a+j)=a -> *(&a[i]+j)=a -> *(*(a+i)+j)=a
总结:
1、a、&a[0]、&a[0][0]的值是一样的,但是意义不一样
2、为什么a不是int **类型的
a+1移动了一个数组(12byte),如果是int **的话加1移动4个字节
3、a指向a[0],a[0]是一个一维数组,所以说a指向了一个一维数组
作业
以下都封装成子函数的形式(指针移动):
1、求一个字符串中有多少个空格
2、求字符串的长度
3、字符串的拷贝
4、字符串的比较
5、求指定字符在字符串中第一次出现的地址
6、求指定字符在字符串中最后一次出现的地址
7、
1----------字符数组的输入
2----------输出
3----------排序
1、求一个字符串中有多少个空格
#include <stdio.h>
#include <string.h>
#define N 30
int count(char * arr);
int main(void)
{
int num= 0;
char arr[N] = "h w h w h w";
num = count(arr);
printf("%d\n",num);
return 0;
}
int count(char * arr)
{
int i,num = 0;
char *p = arr;
for(i = 0;i<strlen(arr);i++)
{
if((int)*(p)==32)
{
num++;
}
p++;
}
return num;
}
2、求字符串的长度
#include <stdio.h>
#include <string.h>
#define N 30
int str_long(char * arr);
int main(void)
{
int i,j,num= 0;
char arr[N] = "hwhwhw";
num = str_long(arr);
printf("%d\n",num);
return 0;
}
int str_long(char * arr)
{
int i,j,num = 0;
char *p = arr;
while(*p)
{
num++;
p++;
}
return num;
}
3、字符串的拷贝
#include <stdio.h>
#include <string.h>
#define N 30
void str_cp(char * arr, char * str);
int main(void)
{
char arr[N] = "hello";
char str[N] = "ok";
str_cp(arr,str);
puts(arr);
return 0;
}
void str_cp(char * arr, char * str)
{
int i,j,num = 0;
char *p = arr;
char *pp = str;
while(*pp)
{
*p=*pp;
p++;
pp++;
}
*p = '\0';
}
4、字符串的比较
#include <stdio.h>
#include <string.h>
#define N 30
int str_compare(char * arr, char * str);
int main(void)
{
int result = 0;
char arr[N] = "hxllo";
char str[N] = "hallo";
result = str_compare(arr, str);
printf("%d\n",result);
return 0;
}
int str_compare(char * arr, char * str)
{
int i,result = 0;
char *p = arr;
char *pp = str;
while(*p && *pp)
{
if(*p != *pp)
{
break;
}
p++;
pp++;
}
result = *p - *pp;
return result;
}
5、求指定字符在字符串中第一次出现的地址
#include <stdio.h>
#include <string.h>
#define N 30
char *str_first(char * arr, char str);
int main(void)
{
char arr[N] = "hello";
char str = 'e';
char * result = str_first(arr, str);
printf("%p\n",arr);
printf("%p\n",result);
return 0;
}
char *str_first(char * arr,char str)
{
char * result = NULL;
char * p = arr;
while(*p)
{
if(*p == str)
{
result = p;
break;
}
p++;
}
return result;
}
6、求指定字符在字符串中最后一次出现的地址
#include <stdio.h>
#include <string.h>
#define N 30
char *str_last(char * arr, char str);
int main(void)
{
char arr[N] = "helle";
char str = 'e';
char * result = str_last(arr, str);
printf("%p\n",arr);
printf("%p\n",result);
return 0;
}
char *str_last(char * arr,char str)
{
char * result = NULL;
char * p = arr;
while(*p)
{
if(*p == str)
{
result = p;
}
p++;
}
return result;
}
7、一个控制台
1----------字符数组的输入
2----------输出
3----------排序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 30
void menu();
void input(char * a);
void output(char * a);
void swap(char * a);
int main(void)
{
char arr[30] = {'\0'};
int fun = 0;
while(1)
{
menu();
printf("请选择功能");
scanf("%d",&fun);
switch(fun)
{
case 1:
input(arr);
break;
case 2:
output(arr);
break;
case 3:
swap(arr);
break;
case -1:
exit(0);
}
}
return 0;
}
void menu()
{
printf("功能菜单\n");
printf("1-数组的输入\n");
printf("2-数组的输出\n");
printf("3-排序\n");
printf("-1-exit\n");
}
//输入
void input(char * a)
{
getchar();
gets(a);
}
//输出
void output(char * a)
{
//puts(a);
for(int i=0;i<strlen(a);i++)
printf("%c\n",*(a+i));
}
//排序
void swap(char * a)
{
int i,j,tmp = 0;
int num = 0;
char * p = a;
while(*p)
{
p++;
num++;
}
printf("%d",num);
for(i=1;i<num;i++)
{
char * pp = a;
for(j=0;j<num-i;j++)
{
if(*(pp)>*(pp+1))
{
printf("2\n");
tmp=*pp;
*pp=*(pp+1);
*(pp+1)=tmp;
}
pp++;
}
}
}
*(++p):先加加,再取值