C博客作业05-指针

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

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

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

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

  • 指针定义:专门用来存放另一个变量的地址,那么就称它为“指针变量”。
  • 指针相关运算:
    指针变量加(减)一个整数:c语言中规定,一个指针变量加(减)一个整数并不是简单的将指针变量的值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量锁占用的内存单元字节数相加减。如:p+i代表地址计算:p+c*i。其中,c为字节数。
    两个指针变量相加减:如果两个指针变量都指向同一个数组中的元素,则两个指针变量值之差是两个指针之间的元素个数。
    两个指针变量比较:若两个指针指向同一个数组元素,则可以进行比较。指向前面的元素指针变量小于指向后面元素的指针变量,其值为0或1(真或假)
    指针变量的赋值:
    p= &a; 表示将变量a的地址赋给p;

p= arry, 表示将数组arry首元素地址赋给P;

p= &arry[i]; 表示将数组arry第个元素的地址赋给p;

p= max, 表示将max的入口地址赋给p,其中max为已定义的函数;

p1= p2, 表示将p2的值赋给p1,其中p1和p2都是指针变量;

p= NULL,不指向任何变量的指针变量为空指针。
注意p=p+1,++p,和(p)++都是将指针p所指向的变量的值加1。而表达式p++等价于(p++)。

  • 指针做函数参数:可以实现返回多个值的功能。

1.2 字符指针

指针如何指向字符串:将指针指向该字符串的首地址。
eg.char *p = str;//定义一个指针变量,里面存放字符数组的首地址
字符串相关函数及函数代码原型的理解:
1.char *strcpy(char* dest, const char *src);把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间,src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
eg.

char a[10],b[]={"COPY"};
//定义字符数组a,b
strcpy(a,b);
//将b中的COPY复制到a中

2.char *strcat(char *dest, const char *src);把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除dest原来末尾的“\0”)。要保证dest足够长,以容纳被复制进来的src。src中原有的字符不变。返回指向dest的指针,src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
3.strcmp(str1,str2)用于比较两个字符串并根据比较结果返回整数,若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
4.strlen(s1):计算给定字符串的(unsigned int型)长度,不包括'\0'在内,返回s的长度,不包括结束符NULL。

1.3 指针做函数返回值

int a(int *p)
注意:
指针的类型要和函数返回值一样
指针在函数内无返回值时应return 0(return NULL)

1.4 动态内存分配

  • 为什么要动态内存分配:
    传统数组长度必须事先指定,而且只能是常量,不能是变量。
    因为数组长度只能是常量,所以它的长度不能在函数运行的过程当中动态地扩充和缩小
    因为数组长度只能是常量,所以它的长度不能在函数运行的过程当中动态地扩充和缩小
    动态数组能很好地解决传统数组的这几个缺陷。
  • 堆区和栈区区别:
    堆区(heap) 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS(操作系统)回收。分配方式类似于链表
    栈区(stack) 函数运行时分配,函数结束时释放。由编译器自动分配释放 ,存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等。其操作方式类似于数据结构中的栈。
    void *malloc(unsigned int size);其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数的返回值是分配区域的起始地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置。一般它需和free函数配对使用。free函数能释放某个动态分配的地址,表明不再使用这块动态分配的内存了,实现把之前动态申请的内存返还给系统。
    void* calloc(unsigned int num,unsigned int size)在内存的动态存储区中分配num个长度为size的连续空间。num:对象个数,size:对象占据的内存字节数,相较于malloc函数,calloc函数会自动将内存初始化为0;

1.5 指针数组及其应用

如果使用指针,可以这么初始化:char *s[] = "I", "love", "you"};
字符串二维数组:char s[3][5] = {"I", "love", "you"};
在字符串数组的初始化上显然更建议用指针数组来进行初始化,这样能更好地利用内存空间。
但在访问字符串数组(或者其他二维数组)上,用数组形式更加简洁、清晰。

1.6 二级指针

如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。

int a =100;
int *p1 = &a;
int **p2 = &p1;

1.7 行指针、列指针

行指针:指向某一行,不指向具体的元素。int (*a)();
列指针:指向行中具体的元素。a[i]

2.PTA实验作业(7分)

2.1 题目名1(2分)

2.1.1 伪代码

定义最大值max=0,length=0,i;
for()
{
     计算字符串s[i]的长度
     if(字符串长度大于max)
     {
           让最大值为此时字符串长度
      }
}

2.1.2 代码截图

2.1.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。

姚庆荣同学的代码:

int max_len( char *s[], int n )
{
	int i, min=0, max=0;
	for(i=0;i<n;i++)
        {
	min=strlen(s[i]);
	if(min>max)
		max=min;
	}
	return max;
}

他的代码特点:简洁明了。运用for循环找到最大值。

2.2 题目名2(2分)

2.2.1 伪代码

2.2.2 代码截图

2.2.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。

姚庆荣同学的代码:

void merge(int* a, int m, int* b, int n)
{
	int i=0, j=0, k=0;
	int* c;
	c = (int*)malloc((m + n) * sizeof(int));
	for (; i<m&&j<n; k++)
	{
		if (a[i] < b[j])
		{
			c[k] = a[i++];
		}
		else
		{
			c[k] = b[j++];
		}
	}
	if (m > n)
	{
		while (i < m)
		{
			c[k++] = a[i++];
		}
	}
	else
	{
		while (j < n)
		{
			c[k++] = b[j++];
		}
    }
	for (i = 0; i < k; i++)
	{
		a[i] = c[i];
	}
}

2.3 题目名3(3分)

2.3.1 伪代码

void ReverseStr(char *beginPtr)
{
    定义尾部指针endPtr=beginPtr
    while(*endPtr)endPtr++//指针定位到字符串尾部
     遍历指针p=--endPtr
     while(!=beginPtr)
     {
          若*p不是空格,则统计单词长度len
          若*p不是空格但是前一个字符是空格:
                     则找到单词,输出从p开始的len长度字符串,len=0
           p--
     }
       输出第一个单词
}

2.3.2 代码截图

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

(参照超星视频做的,所以没差别)
优点:
1:字符串指针能灵活表示某个子串:printf("%.*s",len,p);输出长为len,起始位置为p的字符串。 (%.ms可以输出指定长为m的字符串长度)
2:找单词:指针定位在字符串最后一个字符,往前扫描到第一个空格,即找到一个单词,则输出指定长度字符串。
3:fgets会吸收换行符,所以还要考虑'endPtr!='\n''的情况

posted @ 2020-12-27 22:13  蓝胖子WHM  阅读(192)  评论(0编辑  收藏  举报