C博客作业05-指针
| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业05-指针 |
| 这个作业的目标 | 学习指针相关内容 |
|姓名 | 曹秋秋 |
1.本章学习总结
1.1 指针定义、指针相关运算、指针做函数参数。
指针定义
指针是用来存放地址的变量,C语言中把专门用来存放变量的地址的变量称为“指针变量”,简称指针,如果一个指针变量的值是另一个变量的地址,就称该指针变量指向那个变量。
指针的基本运算
-
相同类型的指针能进行赋值、比较和算术运算。
-
两个指针不能相加,但可以相减,二者的差值表示二者相隔的存储单元。
-
在完成定义后,*表示间接访问运算符,用于访问指针所指向的变量。
-
如 p=p+1、++p 和 (p)++ 都是将指针所指向变量的值加一;而p++等价于(p++) 表示先取*p的值作为表达式的值,再将指针p的值加一。
指针做函数参数
-
调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。
-
在函数定义时将指针作为指针作为形参,在函数调用时将变量的地址作为实参。
-
将指针作为函数的参数就能使函数返回多个值。
1.2 字符指针
字符指针是一个指向该字符串首字符的指针常量
例如:
char *p="string";
printf("%s",p);
以%s的格式输出字符串时,作为输出参数,指针p的值为地址,从首地址所指定单元开始连续输出其中的内容,直到遇到‘\0’。
输出参数给出起始位置,'\0'用来控制结束。
1.3 指针做函数返回值
-
只有函数本身的类型为指针类型,函数返回值才能为指针。
-
返回的指针最好不要指向函数内部定义的变量,因为函数内部定义的变量为局部变量,在函数运行结束后,这些变量会自动销毁。
1.4 动态内存分配
-
这些函数都需要头文件<stdlib.h>
-
由于这些函数都是void类型,但我们的变量没有这种类型,所以在使用时需要进行强制类型转换
-
若我们将会有n个int类型的数要传给int类型的指针p,那么申请动态内存时需要这样写: p = (int*)malloc(n * sizeof(int))
-
当一块空间使用完毕后,要使用free()函数将这块空间释放
void free(void *Ptr)
- 其他动态分配的函数:calloc()、realloc()等
1.5 指针数组及其应用
- 指针数组的定义
一维指针数组定义的一般格式为:
类型名 *数组名[数组长度];
char * color [5];
- 指针数组的应用
可以用指针数组处理多个字符串
例如:
char*pcolor[]={“red","blue","yellow","green","black"};
1.6 二级指针
二级指针是指向指针的指针,表示方法如下:
int **p;
其中,p和p都表示地址,p指向p,而*p指向内容。**p则表示内容。
1.7 行指针、列指针
- 行指针实际上就是二级指针运用于二维数组,在c语言中,二维数组实际上是以一维数组为单位连续存储的,可以说二维数组是特殊的一维数组
-
假设有一个行指针int (*p)[5],它指向a[5][5],那么p指的是a[0]一整行,p+1指的是a[1]一整行,以此类推,他们都不表示一个特定的元素
-
p[1]+1、(p+1)+1两者都指的是a[1][1]的地址,其中p[1]、(p+1)都代表着第1行的首地址,想要取得a[1][1]的值需要对他进行二次取值(如((p+1)+1))
- 列指针
对于一个二维数组:
int a[3][5];
-
我们知道,a即是它的行指针,a+0表示第0行的地址,a+1表示第1行地址…
-
或者可以说成&a[0]表示第0行的地址,&a[1]表示第1行的地址…
-
那么a[0]+0,a[0]+1就表示第1行第1列的地址,第1行第2列地址
-
a[1]+0,a[1]+1就表示第2行第1列地址,第2行第2列地址…
2.PTA实验作业
2.1(指针做函数返回值) 查找指定字符
2.1.1伪代码
定义op为待查找字符
定义指针str为输入的字符串
定义index为找寻的下标
申请动态内存空间
输入字符op
缓冲换行符
自定义SearchIndex()函数
if index=-1 then
输出 not found
else
输出 index=找寻的下标
释放动态内存
int SearchIndex(char* str, char op)
定义i=0
定义index=-1
while 字符串不为0和\n时
if 查找的字符与str[i]相等 then
index=i
i++
continue
i++
返回index
2.1.2代码截图
- 掌握定义指针变量后要申请动态内存空间
str = (char*)malloc(N * sizeof(char));
不同类型变量,即把char进行修改
如若为整型,则:
str = (int*)malloc(N * sizeof(int));
-
注意释放动态内存空间
-
注意对i进行自增
-
注意0与NULL,返回 NULL 和 返回 0 是完全等价的
2.2合并2个有序数组
2.2.1伪代码
定义一个新的指针num,用于存储排列后的数据
定义变量i记录num中的数字个数,j、k分别用于记录a、b中当前是第几个数
为num申请动态内存
while (j+k < m+n) do
如果a中的数都记录完毕,则记录b剩下的数
如果b中的数都记录完毕,则记录a剩下的数
否则将a[j]与b[k]进行判断,记录小的那个数
end while
将num中的内容全部复制给a
释放num
2.2.2代码截图
- 用malloc()函数申请动态内存,使用完毕后使用free()函数释放内存
num = (int*)malloc((m + n) * sizeof(int));
free(num);
- 建立新的指针(数组)保存目标内容,对原始内容进行分部分处理
- 使用memcpy()函数将一个数组的内容复制给另一个数组
memcpy(目标数组,要被复制的数组,要复制的大小)
/*注意事项:
1.需要头文件cstring
2.与strcpy不同,它可以复制任何内容*/
2.3说反话-加强版
2.3.1伪代码
从最后一位开始倒着遍历数组
当碰到一个不为空格的字符时,将该字符的下标赋给tail
当再次碰到空格时将空格所对应的下标加1赋给head,确定该单词头和尾所对应的下标
每遇到一个单词,count++
if count>0 then 输出一个空格
end if
for i=head to i=tail do 输出a[i]
end for
2.3.2代码截图
- 本题因为是要说反话,所以比起正这遍历数组,倒着遍历数组要更方便一些。如何确定一个单词的位置是该题较难的地方,我选择在倒着遍历时,当碰到一个不为空格的字符时就将其下标赋给变量tail,然后再找到该单词的头,然后直接先输出该单词,再去继续寻找下一个单词。