0.展示PTA总分
展示关于“指针题目集”分数截图。
1.本章学习总结
1.1 学习内容总结:
指针做循环变量做法
运用指针传入地址,求n个数的和
int i;
for(i=0;i<n;i++)
{
sum=sum+*p;
}
字符指针如何表示字符串
·C语言中通常是将字符串放在一个字符数组中。
·字符数组归根结底还是一个数组,str也可以认为是一个指针,指针以及数组方面操作均适用。
·除了字符数组外,C语言还支持直接使用一个指针指向字符串的方式来表示字符串,如:
·char *str = "hello C language";
·以此方式定义的字符串,同样可以对此字符串进行多样的操作。它们最根本的区别是在内存中的存
储区域
不一样,字符数组存储在全局数据区或栈区,而以指针形式表示的字符串却存储在常量区。
·全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括
其他数
据)只有读取权限,没有写入权限。
·用一句话概括:数组形字符串存放在全局数据区或栈区,可读可写。指针字符串存放在常量区,只
读不能写
动态内存分配
·所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动
态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要
即时分配,且分配的大小就是程序要求的大小。
·当程序运行到需要一个动态分配的变量或对象时,必须向系统申请取得堆中的一块所需大小的存贮
空间,用于存贮该变量或对象。当不再使用该变量或对象时,也就是它的生命结束时,要显式释放
它所占用的存贮空间,这样系统就能对该堆空间进行再次分配,做到重复使用有限的资源。
###动态分配内存的方法
·new可用来生成动态无名变量
··int *p=new int;
··int *p=new int [10]; //定义一个动态数组常量
··int *p1;
··double *p2;
··p1=new int;
··p2=new double [100];
·l 分别表示动态分配了用于存放整型数据的内存空间,将初值12写入该内存空间,并将首地址值
返回指针p1;
·l 动态分配了具有100个双精度实型数组元素的数组,同时将各存储区的首地址指针返回给指针变
量p2;
###当生成二维及更高维的数组,应使用多维指针。
··int **p=new int* [row]; //p是指向一个指针数组的指针
··for(int i=0; i<row; i++)
··p[i]=new int [col]; //p是指向一个数组的指针
·使用完动态无名变量后应该及时释放,通过使用delete 运算符
··delete p; //释放单个变量
··delete [] p;//释放数组变量
###malloc函数;
·头文件:可以用malloc.h或 alloc.h
·功能:分配长度为num_bytes字节的内存块
·返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,
应使用free()函数将内存块释放。
指针数组及其应用
·一维数组
一般格式:
· 类型明 *数组名[数组长度];
··int a[10];
··int *colour[5];//定义五个元素,分别指向五种不同颜色的地址
··char *temp;
··temp=colour[0];//令第一个数组的值等于一个字符
··colour[0]=colour[4];//将第一个与最后一个进行交换
··colour[4]=temp;
二级指针、行指针
·如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
·有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示:
··int a =100;
··int *p1 = &a;//定义一个一维指针
··int **p2 = &p1;//定义二维指针
·指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址。C语言不限制指针的级数,每增加一
级指针,在定义指针变量时就得增加一个星号*。p1 是一级指针,指向普通类型的数据,定义时有一个*;p2
是二级指针,指向一级指针 p1,定义时有两个*。
·行指针,是指向一行的指针。
··主要用于二维指针
··如a[2][3]={{1,2,3}{4,5,6}},其中a是整个数组的首地址,同时也指向第一行元素,所以a是一个行
指针,它每加1,所指地址移动二维数组的一行,a+1指向第二行元素。
·注意: **a(也可写成a[0][0])就是这个二维数组第一行的第一个元素,**(a+1)(也可写成a[1][0])就是
第二行的第一个元素,*(*(a+1)+1)(也可写成a[1][1])是第二行的第二个元素。可见,对行指针取2次*就
成了某个元素的值了,而不再是地址。
int main(void)
{
int a[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3];
p = a;
p++;
printf("%d",**p);
}
·此段代码输出结果为4,p是个行指针,可以直接将a这个行指针直接赋值给它,此时p也指向二维数组的起始
地址,即第一行。
函数返回值为指针
·如果函数返回的是一个指针(地址),则为指针函数。
·用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部
变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,否则会发生生成错误。
1.2 本章学习体会
1.通过学习了指针,在函数使用时,可以只传地址,而不用像以前一样,传这个组,这样可以节省内存,又提高了传输效率。指针还可实现动态内存分配,避免造成内存浪费。通过函数改变一个变量的值,就得用指针传递。如果用普通变量传递,则无法实现。
2.初学指针,对指针的使用还是不熟练。p是一个内存地址值,p是地址p指向的内容。对p和p的使用还比较模糊。p++即可实现指针#指向数组的下一个元素,指针的使用还是比较方便的。
3.C语言的学习感觉在难度上是一直在递增的,这次学习的指针和地址的概念比较抽象,理解上也比较困难,感觉并不是很能够完全领会,再加上近期的线性代数考试等一些考试的准备,对C语言的学习也有所放松,预习复习不够及时,大量知识点需要在经过自己再重新阅读,PTA写得不是很及时.
2.PTA实验作业
求出数组中最大数和次最大数
·函数 fun 的功能是:求出数组中最大数和次最大数,并把最大数和a[0]中的数对
调、次最大数和a[1]中的数对调。
··求最大值与最小值
··for(从0到2进行比较)//保证值寻找最大数和次大数
·· for(从第i个值开始到k一一比较)//寻找最大数和次大数
·· 进行交换,将最大的数和最小的数与a[0],a[1]交换
·(1)第一次提交将所有的都提交
·(2)在一次时没有没有初始化a[0]的值,交换失败
·(3)在最后的判断时需要使第二次的循环从i++开始,如果不等于;则会寻找
最大值
计算最长的字符串长度
本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度。
·for(i=0到N)
·if(从第一个开始进行比较)
··如果大于等进行交换,直到找到最大值
··return 返回最大值
·(1)对于判断最大值时首先需要循环判断
·(2)返回的是数组,并不是指针地址
·(3)再找到最大值后进行交换
测试值 |
测试点 |
测试结果 |
4 |
有并列最长串 |
|
blue |
重新定义MAXN和MAXS, 取最大边界, 答案超过20 |
|
yellow |
最小n和长度 |
|
green |
sample, 唯一最长串 |
答案正确 |
(指针做函数返回值) 查找指定字符
本题要求编写程序,从给定字符串中查找某指定的字符。
·定义一个指针数组
·for(i=0;数组不等于空格时进行循环)
·count++
· for(i=0;当需要的地址小于count时开始判断)
·if当输入的值等于寻找值时,进行地址交换
·进行输出
·else Not Found
测试值 |
测试点 |
测试结果 |
m |
sample1等价,不唯一,输出最大的下标 |
|
programmin |
重新定义MAXN和MAXS, 取最大边界, 答案超过20 |
|
a |
sample2, not found |
|
1234 |
index = max,字符串中有空格 |
答案正确 |
代码阅读
许多人喜欢解决难题,其中一些可能会导致他们许多人喜欢解决难题,其中一些可能会导致他们疯狂。其中一个难题可能是在给定的文本中找到一个隐藏的素数。这样
的数目可以是文本中存在的给定大小的不同子串的数目。当你很快就会发现,你真的需要一台电脑的帮助和一个好的算法来解决这样一个难题。
您的任务是编写一个程序,给定子字符串的大小N、文本中可能出现的不同字符数NC和文本本身,确定文本中出现的大小N的不同子字符串数。
例如,考虑N=3,NC=4和文本“daababac”。在本文中可以找到大小为3的不同子串:“daa”、“aab”、“aba”、“bab”、“bac”。因此,答案应该是5。
输入
第一行输入由两个数字组成,N和NC,正好被一个空格隔开。后面是搜索发生的文本。您可以假设由可能的字符集所形成的子串的最大数目不超过16百万。
输出
程序应该只输出一个整数,对应于给定文本中大小为N的不同子字符串的数目。
此问题包含多个测试用例!
多个输入的第一行是整数N,然后是空行,后跟N个输入块。每个输入块的格式如问题描述所示。输入块之间有一个空行。
输出格式由N个输出块组成。输出块之间有一个空行。