C博客作业05-指针

这个作业属于哪个班级 C语言--网络2011/2012
这个作业的地址 C博客作业05--指针
这个作业的目标 学习指针相关内容
姓名 李兴果

0.展示PTA总分

1.本章学习总结

1.1 指针定义、指针相关运算、指针做函数参数。

指针的定义:

 指针是一个变量,用来存放地址的变量

* 指针的值:是某个变量的地址
p=&a:把a的值取给p,即p指向a;

**指针变量的类型和它所指向变量的类型一致**
*p:直接对内存单元操作,改变变量的数据
&:取地址,*:取内
&*p与&a相同,为地址
*&a与a相同,是变量
 (*p)++相当于a++:将p所指向的变量值加一;
  *p++等价于*(p++):先取*p,然后p自加,此时p不再指向a;

&a的含义:
pointre_1=
先对a取地址,之后
为a所指向的变量,即
&a与a等价;

指针变量的初始化:

(1)指针变量必须先定义,然后地址赋值
int a;intp;p=&a;

(2)定义指针的变量时,可同时对对它赋初值
int a;int *p=&a;

(3)不能用数值作为指针变量的初值,可将指针变量初始化为一个空指针
p=0;p=NULL



相同类型的指针才能相互赋值

指针实现交换:

  • swap1(a,b),在swap函数中会改变形参的值,但不会影响实参的值
    不能改变main()中实参的值
  • swap2(&a,&b),定义swap(int p1,int p2)将p1和p2交换值之后,主调函数的ab,值也会跟着其变化



传地址可以返回多个变量值

形参:指针变量 int *p
实参:地址&a,某个指针

数组和地址间的关系:

(1) 数组名代表一个地址,它的值是数组首元素的地址
a+i是数组a基地址的第i个偏移量
&a[i]=a+i;a[i]=*(a+i)

(2) 指针与数组的关系:
p=a or p=a[0]

  • 指针做循环变量时候条件
    for(p=a;p<a+n;i++)

指针的运算:

(1)指针+或者-一个数,表示指针加减这个数的类型所占内存的整数倍

(2)指针减去一个指针,表示两个指针之间所差的内存单元或者元素个数,两个指针相加没有意义

(3)关系运算,如果定义了两个指针变量p和q,并且都已经初始化了
p-q:两者之间相差的元素
(int)p-(int)q:两者之间相差的字节数

*和&两个符号优先级是相同的,运算时自右向左

int arr[5] = { 1,3,5,7,9 };

int *p = arr;

  *++p:p先自+,然后*p,最终为3

  ++*p:先*p,即arr[0]=1,然后再++,最终为2

  *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]

  (*p)++:先*p,即arr[0]=1,然后1++,该语句执行完毕后arr[0] =2

  *(p++):效果等同于*p++

指针作为函数参数:

实参和形参之间的数据传输是单向的,实参可以影响形参,而形参不能影响实参。指针但是可以改变实参指针变量所指向的变量的值


1.2 字符指针

(1) const:

  • 定义变量,相当于常量
  • 只读变量,必须在定义时就给之赋值

(2)不要引用未赋值的指针

  • 定义指针时,先将它的初值置为空
    char*s=NULL;

(3)常用字符串处理函数

  • 函数原型在stdio.h或string.h中给出
    输入:scanf or fgets
    输出:printf or puts

(4)

  • 字符串复制:strcpy(str1,str2)

  • 字符串连接:strcat(str1,str2)

  • 字符串比较:strcmp(str,str2)
    比较字符串的内容:
    if(strcmp(str1,str2)>0)
    if(strcmp(str1,str2)<0)
    if(strcmp(str1,str2)==0)

  • 字符串长度:strlen(str)
    计算字符串长度,不包括'\0',fgets()会包括'\0'

  • strcpy与strcat问题
    源字符串需要足够,否则会出现溢出现象

char *strcpy(char *a,const char *b,size_t n)
将b中所指向的字符串复制到a当中,最多复制n个字节,当b中字节少于n个字节时,a中剩余部分将用空字节填充

char *strcat(char *a,const char *b,size_t n)
将b中所指向的字符串追加到a所指向字符串的结尾,追加最多n个字符

  • strpbrk(str1,str2)
    char *strpbrk(const char *str1,const char *str2)
    检索字符串str1中第一个匹配str2中字符串的字符

  • strrchr()
    char *strrchr(const char *str,int c)
    参数str所指向字符串中最后一次出现字符c的位置

  • strstr()
    char *strstr(const char *haystack,const char *needle)
    字符串haystack中寻找第一次出现字符串needle的位置

  • 引用数组元素:
    指针法:*(a+i)or *(p+i)//a为第一个元素的地址,+i指向第i个元素,若为int类型,则i为四个字节

三目运算符
对于条件表达式b ? x : y,先计算条件b,然后进行判断。如果b的值为true,计算x的值,运算结果为x的值;否则,计算y的值,运算结果为y的值。一个条件表达式绝不会既计算x,又计算y。条件运算符是右结合的,也就是说,从右向左分组计算

1.3 指针做函数返回值

  • 具体格式:
  char *fun()
{
char *;
.......
return p;
}
  • 要求设计函数match(s,ch),在字符串s中查找字符ch,如果找到,返回第一次找到的该字符在字符串中的位置(地址),否则,返回空指针NULL

1.4 动态内存分配

为什么要动态内存分配,堆区和栈区区别。动态内存分配相关函数及用法。举例为多个字符串做动态内存要如何分配。
(1)

  • 优点:能够根据实际输入数据的多少来申请和分配内层空间,从而提高内存使用率
    (2)
  • 堆区和栈区区别:
    1.申请方式不同
    栈:有系统自动分配
    注意:系统首先会去查看栈上是否有足够的区域去开辟该空间,如果有就直接开辟,如果没有则栈溢出
    堆:自己申请开辟,并且指明大小
    2.底层不同
    栈:是连续的空间
    堆:不是连续的空间

(3)

  • molloc函数:malloc 函数的返回值是一个地址,这个地址就是动态分配的内存空间的起始地址。如果此函数未能成功地执行,如内存空间不足,则返回空指针 NULL。
    有molloc也要有free,申请后要释放,解放内存

  • free函数:无返回值,它的功能是释放指针变量 p 所指向的内存单元。此时 p 所指向的那块内存单元将会被释放并还给操作系统,不再归它使用。操作系统可以重新将它分配给其他变量使用。

1.5 指针数组及其应用

多个字符串用二维数组表示和用指针数组表示区别?

一维数组定义的一般格式:类型名 *数组名[数组长度]
指针可以相互转换(时间空间更优化)

1.6 二级指针

定义:指向指针的指针

类型名 **变量名
int a=10;
int *p=&a;
int **p=&p;

1.p变了,pp也跟着变

2.地址加数值还是地址

3.二级地址,一个后是一级地址,2
后才是内容
a+i=a[i],二级指针

*(a+i):a[i],表示第i行首元素地址,一级指针
*(a+i)+j:a[i]+j=&a[i][j],第i行第j个地址,一级地址
**(a+i):a[i][0]
((a+i)+j):a[i][j]
a+i+j:第i+j行二级地址

1.7 行指针、列指针

定义格式、主要用法。
行指针
int (*p)[n]

  • 含义:p为指向含有n个元素的一维数组的指针变量,二级指针
  • 行指针p是行地址性质的指针,p+i=a+i!=a[i]二级指针
    (p+i)=(a+i)=a[i]一级指针
  • 行指针可以和数组名互相使用,p[i][j]=a[i][j]

二级指针

一个*,表示地址
两个**,表示元素
*(*(p+i)+j)=a[i][j]
  • 列指针:
int
*p;
p=a[0];
*(p+i),表示离a[0][0]第i个位置的元素
  • 行指针:
p+i:表示第i行的首地址a[i],二级指针
a[i][j]=*(*(p+i)+j)=(*(p+i))[j]=p[i][j]

指针数组:

int *p[n],int **p;p=pp;
p[i]为指针
p为二级指针

2.PTA实验作业

2.1 题目名1

2.1.1 伪代码

定义初始化变量s1,s2
定义 i, num
  输入
strstr(s1, s2)当s1寻找到在s2中第一次出现的词
   长度为s1中找到的
   char* p = strstr(s1, s2)返回在s1中找到的第一个s2字符串地址 
  定义cnt = strlen(p)  cnt等于所找到的当前s2字符串地址之后所有的字符串个数 
		当i != strlen(s2)
		对p中的s2字符串置'\0',并将p移至下一个地址 
	往前移位,即num-cnt为当前s1字符串的字符个数 
	num = strlen(s1)
	输出

2.1.2 代码截图

2.1.3 找一份同学代码

2.2 题目名2

2.2.1 伪代码

 定义i = m - 1//i为a数组下标
 定义j = n - 1//b数组下标
定义 k = m + n - 1//为新数组a的下标
   当i,j值都大于0
   如果(a[i] >= b[j])
 将两数组当中最大的值赋给新数组a中最大的位置
            i--
            j--
当其中一组数排列完毕,剩下一组数则放置新数组a的前面位置
        a[k--] = b[j];
        j--

2.2.2 代码截图

2.2.3与同学代码区别

  • 我的代码:
    从下标开始,定义合并后数组下标
    从最后一个数开始遍历
    比较大小,移动数的位置

  • 同学的代码:
    采用动态内存分配
    循环条件直到数组读取结束
    分别存储a结束后存b/b存完存a

2.3 题目名3

(本题没有做出来)

2.3.1 伪代码

2.3.2 代码截图

2.3.3 请说明和超星视频做法区别,各自优缺点。

老师的代码

知识点
定义指针指字符串,更能动态了解当前字符及位置
while (* endPtr&&* endPtr != '\n') endPtr++;
逆向扫描字符串
while (p != beginPtr) { p--; };
寻找字符串中单词,即当前一个字符为空格时候
if(* p != ' '&&* (p-1) == ' ');//当前字符非空格而前一个字符是空格
输出指定长度字符printf("%.s",len,str);

posted @ 2020-12-27 21:08  Li-xinguo★  阅读(146)  评论(0编辑  收藏  举报