1.本章学习总结(2分)
1.1 学习内容总结
1.指针变量的定义和指针变量的基类型
定义指针的一般形式如下:
类型名 *指针变量名1,*指针变量名2,……..;
例如:int *pi,*pj;
在每变量前的星号*是一个说明符,用来说明该变量是指针变量。注意:变量前的星号说明符不可省略,省略了就变成了定义整型变量。
基类型
int *p;
int 是类型名,说明了pi和pj是两个指向整形(int类型)变量的指针,也就是说变量pi和pj中只能存放int类型变量的地址,这时我们就称int是指针变量pi和pj的基类型。又如:
double *pd; char *s1,*s2;
其中pd是的基类型为double类型,在指针变量pd中,只能存放double类型变量的地址;s1和s2的基类型为char类型,在s1和s2中只能存放char类型变量的地址。
2.指针变量的初始化
通过&获得地址值
int i;
int*p=&i;
变量必须与已定义类型一致
注:int i;
static int *p;
错误 不能用auto变量的地址去初始化static整形指针。
通过指针变量获得地址值
int i;
int *p=&i;
int *q=p;
用已初始化的指针变量作初值,p和q指向同一地址。
注:int a,b,*p1,*p2;
*p1=10;*p2=20;
错误 指针变量储存确定的地址值才能使用,否则会造成系统崩溃
通过标准函数获得地址值
int *pi;
pi=(int *)malloc(4); malloc返回void*
给指针变量赋“空”值
int *p;
p=NULL;
//NULL的代码值为0,当执行了以上的赋值语句后,称p为空指针
指针p并不是指向地址为0的储存单元,而是具有一个确定的值的----“空”,企图通过一个空指针去访问一个存储单元时,将会得到一个出错信息。
3.指针与数组
1.指针数组(存放指针的数组)
一个数组,及其元素均为指针类型的数据——指针数组
一维指针数组:类型名 数组名[数组长度];
二维指针数组:类型名 数组名[行][列];
一维数值指针数组
二维数值指针数组
2.数组元素指针(指向数组元素的指针)
数组元素在内存中分配的地址——数组元素的指针
定义一个指向数组元素的指针
设定一维数组名代表了数组第一个元素的地址
引用数组元素
1.下标法:array[1];
2.指针法:(p + i);或(array+i);
3.数组指针(行指针)(指向数组的指针)
数组元素在内存中的起始地址——数组元素的指针
定义一个数组元素的指针
数组在内存中的起始地址称为数组的指针
4.字符指针
- 字符指针:指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。即将字符串的首地址赋值给字符指针,可让字符指针指向一个字符串。
char *ptr = "Hello";
//将保存在常量存储区的"Hello"的首地址赋值给ptr
与
char *ptr;
ptr = "Hello";
//是等价的,注意不能理解为将字符串赋值给ptrchar str[10] = "Hello";
char *ptr = str;
//数组名代表数组的首地址
//等价于
char *ptr;
ptr = str;
//等价于ptr = &str[0];将数组的首地址赋给字符指针ptr对于数组名str,不能使用str++操作使其指向字符串中的某个字符,因为数组名是一个地址常量,其值是不能被改变的。
*(ptr+i):字符串中第i+1个字符,相当于*(str+i),即str[i]
也可以用ptr++,移动指针ptr,使ptr指向字符中的某个字符
字符串的长度(指字符串所含的字符个数,但不包括最后的’\0’)与字符数组的大小(指字符串所包含的字符个数加上’\0’,故+1)不一样。
5.指针做函数参数
在c语言中实参和形参之间的数据传输是单向的“值传递”方式,也就是实参可以影响形参,而形参不能影响实参。指针变量作为参数也不例外,但是可以改变实参指针变量所指向的变量的值。
6.二级指针、行指针
- 二级指针:指针的指针。(用来保存一级指针的地址的变量。)
一级指针与二级指针区别:一级指针使用来保存普通变量的地址的变量而二级指针则是用来保存一级指针的地址的变量(指针只能存储地址)。
- 行指针:指向数组的指针,即如指针类型中的 int (*a)[n];。
在有些情况,为了使代码具有可复用行,可以考虑使用列指针。
7.指针数组及其应用
指针数组(存放指针的数组)
例如:char *p[10]; float *p[10];int * q[4][3];
一个数组,及其元素均为指针类型的数据——指针数组
一维指针数组:类型名 数组名[数组长度];
二维指针数组:类型名 数组名[行][列];
- 一维数值指针数组:
int array[8] = {1,2,3,4,5,6,7,8};
int *p[6] = {&array[0],&array[1],&array[2],&array[3]};
p[4] = &array[4];
p[5] = &array[5];
- 二维数值指针数组:
int *a[2][3];
a[0][1] = &array[0];
- 指针数组与字符串的联系:
char *name[2] = {"hello","world"};
name[0] = "hello";
name[1] = "world";
数组中存放的是字符串的首地址,而不是字符串。
8.指针做函数返回值及其注意
指针作函数返回值
返回指针值的函数,一般定义形式:类型名 函数名(参数列表);例如:int fun(int x,int y);
在调用时要先定义一个适当的指针来接收函数的返回值,这个适当的指针其类型应为函数返回指针所指向的类型。
char *pc = NULL;
pc = (char *)malloc(100 * sizeof(char));
表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc
1.2 本章学习体会
指针的本质其实是地址,指针变量就是存放另一变量的地址。我们可以利用指针直接对内存进行操作,利用存放变量的地址找到变量。所以,学习指针有着许多的好处,例如:1.指针可以提高效率。C语言是一种偏底层的语言,为了更直接对内存进行操作,必须使用指针。因为指针是根据内存的地址来操作变量。了解过汇编语言的朋友,可能会知道汇编语言中有寻址这个操作,指针和寻址有异曲同工之妙。另外,如果需要传输大量的数据,可以通过传输起始地址和结束地址来代替(即传递指针),前提是储存的数据地址必须是连续的。2.指针可以提高灵活度。了解过数据结构的朋友都知道链式储存结构。尽管数据的储存单位不是连续的,但并不影响这些数据的逻辑关系。指针就是实现链式储存结构的桥梁,通过指针把这些分散在内存不同地方的数据联系起来。
本周代码量:542
2.PTA实验作业(7分)
2.1 查找子串
2.1.1 伪代码
定义指针变量p,用于存储对应首字符的地址,定义整型变量i,j用于控制循环,定义整型变量k,用于存储返回地址对应数组元素的下标,定义整型变量l1,l2,用于存储原字符串和子串的长度。
for (i = 0; i < l1; i++)
if(原字符串中的某字符与子串首字符相同)
k=i;
for (j = 0; j < l2; j++)
循环判断子串后面的元素与原字符串是否对应
对应 continue;
否则 break;
end for
if(j==l2) 将对应首字符的地址赋给指针变量p并返回p
end if
end for
查找不到子串 return NULL
2.1.2 代码截图
2.1.3 总结本题的知识点
1.掌握在字符串中查找子串做法。
2.注意在原字符串中遍历子串后退出循环的条件。
3.注意在不同查找情况下返回的值。
2.1.4 PTA提交列表及说明
提交列表说明:
1.部分正确:l1误打为12
2.部分正确:没有考虑到在对应子串前出现对应首字符的情况,而直接结束了程序。
3.答案正确
2.2 合并两个有序数组(2)
2.2.1 伪代码
定义整型变量i,j,k,分别用于存放数组a,b,c的下标,定义指针变量c,作为动态分配的新数组地址,用于存放合并后的数组元素。
for(;i
2.2.2 代码截图
2.2.3 总结本题的知识点
1.掌握合并两个有序数组的方法。
2.注意需要使用到动态存储空间的分配。
3.注意在较短数组判断完后,另一个数组剩余元素的处理。
2.2.4 PTA提交列表及说明
提交列表说明:
1.编译错误:没有定义指针变量p
2.部分正确:数组转换赋值方式错误
3.答案正确
2.3 字符串的冒泡排序
2.3.1 伪代码
定义整型变量N,K,来自于题目输入要求,定义二维数组a,用于字符串的输入,定义一维数组a1,用于排序过程中的元素交换,定义整型变量i,j,用于控制循环,定义整型变量bj,用于存储字符串使用函数strcmp比较后的判断值。
for (i = 0; i < N; i++)
输入字符串数组
end for
for (i = 0; i < K; i++)
for (j = 0; j < N - i - 1; j++)
调用函数strcmp比较字符串a[j], a[j + 1]并将判断值赋给bj
if (bj > 0)
元素a[j], a[j + 1]交换
end if
end for
end for
for (i = 0; i < N; i++)
输出排序后的数组
返回0
2.3.2 代码截图
2.3.3 总结本题的知识点
1.掌握字符串的冒泡排序的方法。
2.注意冒泡排序的遍历次数控制。
3.注意字符串交换所需要用到的strcpy函数和转换方法。
2.3.4 PTA提交列表及说明
提交列表说明:
1.编译错误:使用strcpy函数前没有在头部位置添加string头文件
2.编译错误:字符串交换时误将字符类型a1[n]变量作为中置物
3.答案正确
3.阅读代码(-2--1分)
优点及可以学习地方
1.代码边界处理得很好
2.编程较其他解题方法实现得更加简单易懂一点
3.时间常数上可能不占优势,但是渐进复杂度是一样的