C语言博客作业05--指针

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

0.展示PTA总分(0----2)

展示关于“指针题目集”分数截图。

1.本章学习总结(3分)

整理指针主要知识点,必须包含内容有:

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

每个知识点具体展开介绍。

指针定义:

指针,是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围的整数。

在程序中声明一个变量并使用地址作为该变量的值,这个变量就是指针变量。

类型名 *指针变量名;

指针相关运算:

  int i,*p;
  p=&i;             //p指向变量i或存放i的地址。
  p=Null;           //p指向了一个地址为0的内存,赋值给指针时代表空指针。
  p=(int*)1732;     //使用强制类型转换(int *),p指向地址为1732的int型变量,不常用。

将指针p所指向变量的值加1

*p=*p+1;
++*p
(*P)++

将*p的值作为表达式的值,再将指针p的值加1

*p++
*(p++)

指针赋值

int a=3,*p1,*p2;   //定义整型变量指针p1和p2
p1=&a;             //使指针p1指向整型变量a
p2=p1;             //将p1的值赋给指针p2,p2也指向整型变量a

注意:只能将一个指针的值赋值给另一个相同类型的指针。

指针做函数参数:

将变量的地址作为函数的实参时,相应的形参就是指针。

当指针变量作为函数参数时,

1.2 字符指针

包括指针如何指向字符串、字符串相关函数及函数代码原型的理解、字符串相关函数用法(扩展课堂未介绍内容)

指针如何指向字符串:

指针如何指向字符串
	char a[5] = "wolf";     //定义字符数组
	char* p = a;            //指针指向该数组

	printf("%s", p);        //输出首地址字符
	printf("%s", p+n);      //输出首地址之后第n-1个位置对应的地址下的字符

字符串相关函数及函数代码原型:

Strcat函数原型:

char *strcat(char *strDest, const char *strScr) //将源字符串加const,表明其为输入参数
{
       char * address = strDest;             
       assert((strDest != NULL) && (strScr != NULL)); 
       while(*strDest)             //是while(*strDest!=’\0’)的简化形式
       {                        
              strDest++;               
       }                        
       while(*strDest++ = *strScr++) 
       {
              NULL;                 
       }                      
    return address;               
}
           

Strcpy函数原型:

char *strcpy(char *strDest, const char *strScr)
{
       char *address=strDest;
       assert((strDest != NULL) && (strScr != NULL));
       while(*strScr)                   //是while(*strScr != ’\0’)的简化形式;
       {
              *strDest++ = *strScr++;
       }
       *strDest = '\0';                       
       return address;                      
}

3、Strcmp函数原型:

int strcmp (const char *str1,const char *str2)
{           
       int len = 0;
       assert((str1 != '\0') && (str2 != '\0'));
       while(*str1 && *str2 && (*str1 == *str2))
       {
              str1++;
              str2++;
       }
       return *str1-*str2;
}

Strlen函数原型:

int strlen(const char *str)
{
    int len = 0;
       assert(str != NULL);
       while(*str++)
       {
              len++;
       }
       return len;
}

字符串相关函数:

函数名 定义 功能 返回值
strcmp int strcmp(char* str1, char* str2); 比较字符串 返回正值或者1;返回0;返回负值或者-1;
strcat char* strcat(char* str1, char* str2); 连接字符串 str1字符串的首地址
strcpy char* strcpy(char* str1, char* str2); 复制字符串 str1字符串
strlen int strlen(char* str1); 求字符串长度 字符串长度

1.3 指针做函数返回值

具体格式是什么,注意事项。

具体格式:

void Change(char *p) 
            { 
               *p = 'b'; 
            } 
            void main() 
            { 
               char a = 'a'; 
               char* p = &a; 
               Change(p); 
               printf("%c\n", a);           //改变a值 

            }

注意事项:

指针做函数返回值时应该返回地址,因为函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式####参数。

1.4 动态内存分配

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

动态内存分配的原因:

动态的分配内存。可以做到准确分配空间大小。不浪费资源,而且也不会发生程序不断使用预先分配内存不足。

堆区和栈区:

堆区:内存由用户通过动态分配获取,并指明大小

栈区:栈区内存由系统自动分配,函数结束时释放

申请效率:栈由系统自动分配,速度较快;堆是由new分配的内存,一般速度较慢,容易导致内存碎片出现,但是使用方便。

动态内存分配函数及用法:

动态储存分配函数malloc:

函数原型:
void *malloc(unsigned size);

p=(int *)malloc(n*sizeof(int));
//

计数动态储存分配函数calloc

void *calloc(unsigned n ,unsigned size)

分配调整函数realloc()

void *realloc (void *ptr ,unsigned size)

1.5 指针数组及其应用

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

二维数组:存放字符

char str[i][j] = { "have","nice","day"};

指针数组:存放地址

char * str[] ={"joker","always","like","smiling"};

1.6 二级指针

指针是一种变量,它本身也是可用指针指向的对象。

一级指针表示所指向变量的首地址。

二级变量表示对应值。

int  * p1;
int  * * p2;
p2=&p1;

1.7 行指针、列指针

定义格式

行指针: int (*p)[n]

列指针: int *p;

主要用法

示例1:用列指针输出二维数组。

#include<stdio.h>
void main()
{
   int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
   int *p= a[0];               // 列指针的定义法
     for(; p < a[0] + 12; p++)
    {
    printf("%d ",*p);
    }
   return 0;
}

示例2:用行指针输出整个二维数组。

#include<stdio.h>
void main()
{
   int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
   int (*p)[4]= &a[0]; // 行指针定义法或者int (*p)[4]= a;
   int i, j;
   for(i = 0; i < 3; i++)
  {
     for(j = 0; j < 4; j++)
   {
     printf("%d ",*(*(p + i) + j));
   }
     return 0;
  }
}

2.PTA实验作业

2.1 题目名1

2.1.1 伪代码

定义 i,j,k,slen,tlen ;
char *p=NULL;
将slen赋值主串长度
将tlen赋值子串长度

for  0 to slen-1   do
  j=i;
  while(主串和子串出现相同)
   k++;
   j++;
    if(k值大于等于子串长度)
     将主串位置传递给p;
     返回p值。
    end if 
     k=0       //清零,开始下一轮
    end while
end  for
未找到,则最终返回p初值NULL

2.1.2 代码截图

2.1.3 找一份同学代码比较,说明各自代码特点。

我的代码:遍历s主串,当s主串与t子串中元素对应时,进行累加,当累加次数超出或等于t子串长度时,返回子串t在s中的首地址。如果没有,则将null输出。

同学代码:先遍历主串,如果有和子串相同,记录其在主串中坐标,在子串主串同时移动,出现不相同或者子串结束停止。

移动结束后,若子串在结束符,说明找到,返回主串位置,否则则表明未找到,子串回到首位,继续下一轮移动。

2.2 题目:合并2个有序数组。


2.2.1 伪代码

定义 i=0,j=0,k=0;
定义 新指针c进行内存动态分配,可存放下m+n个元素;
while(i+j<m+n)    //未完成合并时
  if(j>=n)          //b数组放完,只需放a数组
   then c[k++]=a[i++];
   else if (i>=m)        //a数组放完,只需放b数组
    then c[k++]=b[j++];
//a、b数组都没放完,比较a、b数组此时需放置的元素数组大小
   else if (a数组元素小于b数组)
    then   放置a数组元素
  else
    then   放置b数组元素
  end if
for  from 0 to m+n-1
   将排序好的c输入回a数组。
end for

2.2.2 代码截图

2.2.3 同学代码比较,说明各自代码特点。

展示同学代码:

代码特点:

同学的想法是从后往前判断,把b数组直接放入a数组。

我的想法是借用指针c,将a、b数组排好序后再放回a数组。

2.3 题目名3 说反话-加强版

2.3.1 伪代码

 定义 数据数组a,指针变量p,j,flag,number,len。
 fgets读取数据
 for p from a+len-1 to 0 //逆向判断   
   do if(对应数据不是空格)
    then number++     //当前单词字母数累加
   else if(number不为0)
    then 
      if(flag==1)
         then  flag=0     //标志可以输出
      else 
       输出空格
      end if
        for j from p+1 to p+number 
         do 正向输出该单词
        end for
    number=0
  end for
  if(只有一个单词)
   then  输出空格
  end if
  for j from p+1 to p+number 
   do 正向输出该单词
  end for

2.3.2 代码截图

根据超星视频和询问同学后


数组做法


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

超星视频代码:使用函数封装,让主函数简单清晰,同时调试方便。

使用flag作为标志符,用if语句判断单个单词的特殊情况,但感觉还可以简化。

送懒惰的自己一句话:
    It's impossible,so more worthy to be believed.
                                                         Faust 6420
posted @ 2020-12-20 20:30  落叶满长安  阅读(78)  评论(0编辑  收藏  举报