C语⾔头歌educoder实训作业答案分享指针(⼀)第⼀关:指针的使⽤
本关任务:使⽤指针对三个整数进⾏排序。
相关知识:
指针的使⽤
指针是⼀种特殊的数据类型,它存的是某⼀个变量的地址,利⽤这个地址可以间接的访问这个变量。
声明⼀个指针变量需要指明能够指向的变量的类型,即指针的类型,并且在变量名前⾯加上*,⽐如:
1. int *ptr; //声明⼀个能指向int类型变量的指针
2.
3. char *str; //声明⼀个能指向char类型变量的指针
指针变量也是变量,因此也可以有指针的指针,⽐如:
1. int **ptr2; //声明⼀个能指向int*变量,即指针变量的指针
注意:变量名前⾯的*并不是变量名的⼀部分。
与指针相关运算符
如果想要获取⼀个变量的地址,就可以⽤**&取地址**运算符,⽐如:
1. int a = 0;
2. int *ptr;
3. ptr = &a; //取得a变量的地址,并将其赋值给ptr
4.
5. char *str = &a; //错误,指针类型不匹配
有取地址运算符,⾃然也就有通过地址取值的***指针**运算符,⽐如:
1. int a = 0;
2. int *ptr = &a;
3.
4. cout << *ptr << endl; //在表达式中是读取所指变量的值
5. *ptr = 10; //在等号左边是赋值给所指变量
6. cout << a << endl;
得到的结果是:
010
可以看到我们通过指针ptr修改了变量a的值。
要注意的是,指针变量虽然存的是地址,但是不能⽤整型直接赋值的,⽐如:
指针变量本身有地址吗1. int *ptr;
2. ptr = 10; //错误,不能直接⽤整型赋值
3. ptr = (int*)10; //可以通过强制类型转换赋值,但除⾮很了解内存布局,否则这么做⼀般会出现程序异常
但是有⼀个特例,那就是赋值0的时候,这个时候表达的含义是空指针,⽐如:
1. int *ptr;
1. int *ptr;
2. ptr = 0; //这个是可以的
注意:与其他变量⼀样,没有初始化或者赋值的指针变量存的值是随机的,如果此时直接使⽤*运算符,则会因为访问了不属于程序的内存位置⽽发⽣异常。也就是所谓的访问越界。
编程要求
在右侧编辑器中有⼀个函数Max,它有三个参数a,b,c,是三个指针,指向三个整型变量。
请在这个函数中,将这三个指针所指的整数从⼩到⼤依次放到a,b,c所指的变量中。
输⼊数据由评测系统读取,并传递给Max函数,之后会将a,b,c所指变量依次输出。具体见测试说明。
测试说明
平台会对你编写的代码进⾏测试:
预期输⼊:2 3 1 预期输出:1 2 3
预期输⼊:2 1 1 预期输出:1 1 2
每组输⼊为⼀⾏,有三个整数,分别代表a,b,c所指变量的值。
#include <iostream>
using namespace std;
void Max(int *a,int *b,int *c)
{
/********** Begin **********/
if((*a)>*(b)){
int temp = *a;
*a = *b;
*b = temp;
}
if((*a)>*(c)){
int temp = *a;
*a = *c;
*c = temp;
}
if((*b)>*(c)){
int temp = *b;
*b = *c;
*c = temp;
}
return ;
//补充代码完成任务
/********** End **********/
}
第⼆关:指针运算
任务描述
本关任务:使⽤指针反转数组元素。
相关知识
指针运算
除了*、&运算符,指针变量还可以与整型进⾏+,-运算,以及使⽤⾃增++、⾃减--运算符。
指针变量使⽤这些运算符时,增加或减少的值是与指针的类型相关的。⽐如对于int *b,且int为32位时,b + 1就是地址值增加4,即越过了⼀个**int变量的长度**。同理,对于b + 2,则是增加8。
⽐如:
1. int *b = 0;
2. cout << b <<endl;
3. b++;
4. cout << b << endl;
5. b += 3;
6. cout << b << endl;
7.
8. char *s = 0;
9. cout << (int)s << endl; //需要强制转换为int,不然会按照字符串输出,导致访问越界
10. s++;
11. cout << (int)s << endl;
12. s += 3;
13. cout << (int)s << endl;
得到的结果是:
00x40x10
014
可以看到对于int类型的指针,加⼀等于地址值加四,⽽char型指针地址值则只是加⼀。
指针之间的运算
指针除了可以与整数进⾏运算,同类型的指针之间也可以运算,不过仅能进⾏减法运算,⽽且结果同样是与类型相关的。
当同类型的两个指针进⾏减法运算时,得到的值是两个指针地址值之差除以指针的类型的字节数,⽐如:
1.
2. int *a = 0;
3. int *b = (int*)8;
4.
5. cout << b - a << endl;
得到的结果是:
2
即(8 - 0) / 4 = 2。
指针之间的减法与指针和整型的运算的道理是相通的,都是以指针类型为基础。
指针变量的⽐较
由于指针变量存的是地址值,因此⽐较时也是⽐较地址值,并且是看做⽆符号数,⽐如:
1. int *a = (int*)-1; //⽆符号数0xffffffff
2. int *b = 0;
#include <iostream>
using namespace std;
void Reverse(int *start,int *end) {
/********** Begin **********/ while(start < end)
{
int temp = * end;
*end = *start;
*start = temp;
start++;
end--;
}
/
/补充代码完成功能
/********** End **********/
}
第三关:指针与数组
任务描述
本关任务:对⼀个数组中的元素进⾏分拣。
相关知识
指向数组的元素
编程要求
右侧编辑器中有⼀个函数Split,它有两个参数arr和len,arr指向⼀个数组,这个数组的长度是len。
arr数组只包含1,0两种值,请在这个函数中补充代码,将这个数组中的0都放在数组的左边(即地址值⼩的那⼀边),1都放在数组的右边。
输⼊数据由评测系统读取,并传递给Split函数,然后会将arr所指的数组的内容输出。详细见测试说明。
测试说明
平台会对你编写的代码进⾏测试:
预期输⼊: 51 0 1 1 1 预期输出: 0 1 1 1 1
预期输⼊: 30 1 0 预期输出: 0 0 1
每组输⼊有两⾏,第⼀⾏是⼀个数n,第⼆⾏有n个数,为数组的内容。
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
void Split(int *arr,int len)
{
/********** Begin **********/
int *start = arr;
int *end = arr+len-1;
while(true)
{
while(start < end && *start == 0)
start++;
while(start < end && *end == 1)
end--;
if(start < end)
{
int temp = *start;
*start = *end;
*end = temp;
}
else{
break;
}
}
//补充代码完成功能
/********** End **********/
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论