9.1 指向指针的指针
T ** p:p是指向指针的指针,p指向的地方存放着一个类型为T*的指针,*p的类型是T*。
9.2 指针和字符串
字符串常量的类型是char*,字符数组名的类型也是char*。
9.3 字符串库函数
int atoi(char* s); 将字符串s里的内容转换成一个整型数返回。如果s的格式不是整数,则返回0。
double atof(char* s); 将字符串s中的内容转换成实数返回。如果格式不为实数,则返回0。
char* itoa(int value, char* string, int radix); 将整型值value以radix进制表示法写入string。
9.4 void指针和内存操作函数
void* p 可以用任何类型的指针对void指针进行赋值或初始化。
void* memset(void* dest, int ch, int n); 将从dest开始的n个字节,都设置成ch,返回值是dest。ch只有最低的字节起作用。
eg. char szname[100] = ""; memset(szname, 'a', 10);
用memset函数将数组内容全部设置成0:int a[100]; memset(a, 0, sizeof(a));
void* memcpy(void* dest, void& src, int n); 将地址src开始的n个字节,拷贝到地址dest,返回值是dest。
eg. int a1[10]; int a2[10]; memcpy(a2, a1, 10*sizeof(int));
9.5 函数指针
每个函数都会占用一段连续的内存空间,函数名就是该函数所占内存区域的起始地址(也称入口地址)。将函数入口地址赋给一个指针变量,称该指针为函数指针。
类型名 (* 指针变量名)(参数类型1, 参数类型2...) eg. int(*pf)(int, char) pf是一个函数指针,所指向函数的返回值为int,该函数有两个参数,分别是int和char。
可以用一个原型匹配的函数名给一个函数指针赋值。通过函数指针调用其指向函数的写法为:函数指针名(实参表);
快速排序库函数:void qsort(void* base, int nelem, unsigned int width, int(*pfCompare)(const void*, const void*));
base:起始地址,nelem:元素个数,width:每个元素的大小(字节为单位),pfCompare:比较函数的地址。
作业
1.指针练习:输出Hello
Description:下面程序片段的输出结果是 Hello ,请填空。
1 #include <iostream>
2 using namespace std;
3 int main() {
4 char s[] = "Hello";
5 char * p;
6 for(
7 // Your Code Here
8 )
9 cout << * p ;
10 return 0;
11 }
Input:(无)
Output:Hello
Sample Input:(无)
Sample Output:Hello
p=s; *p; p++
2.指针练习:输出Tesla
Description:下面程序输出结果是 Tesla Tes 请填空。
1 #include <iostream>
2 using namespace std;
3 void Print(const char * p1, const char * p2)
4 {
5 for(
6 // Your Code Here
7 )
8 cout << * p1;
9 }
10 int main()
11 {
12 const char * s = "Tesla123";
13 Print(s,s+5);
14 cout << endl;
15 Print(s,s+3);
16 cout << endl;
17
18 return 0;
19 }
Input:(无)
Output:
Tesla
Tes
Sample Input:(无)
Sample Output:
Tesla
Tes
; p1<p2; p1++
3.指针练习:ForEach
Description:程序填空,使得输出结果为:1,4,9,16,25, h,e,l,l,o,!,
1 #include <iostream>
2 using namespace std;
3
4 void ForEach(void * a, int width, int num,
5 // Your Code Here
6 )
7
8 {
9 for(int i = 0;i < num; ++i)
10 f((char*)a+width*i);
11 }
12
13 void PrintSquare(void * p)
14 {
15 int * q = (int*)p;
16 int n = *q;
17 cout << n * n << ",";
18 }
19 void PrintChar(void * p) {
20 char * q = (char*)p;
21 cout << *q << ",";
22 }
23 int main()
24 {
25 int a[5] = {1,2,3,4,5};
26 char s[] = "hello!";
27 ForEach(a,sizeof(int),5,PrintSquare);
28 cout << endl;
29 ForEach(s,sizeof(char),6,PrintChar);
30 return 0;
31 }
Input:(无)
Output:
1,4,9,16,25,
h,e,l,l,o,!,
Sample Input:(无)
Sample Output:
1,4,9,16,25,
h,e,l,l,o,!,
void (*f)(void*)
4.指针练习:Memcpy之一
Description:程序填空,使得程序按要求输出。
1 #include <iostream>
2 using namespace std;
3 void Memcpy(char * src,char * dest,int n)
4 {
5 // Your Code Here
6 }
7 int Strlen(char * s)
8 {
9 int i;
10 for( i = 0; s[i]; ++i);
11 return i;
12 }
13 int main()
14 {
15 int a;
16 char s1[30];
17 char s2[30];
18 int t;
19 cin >> t;
20 for(int i = 0;i < t; ++i) {
21 cin >> a;
22 int b = 99999999;
23 Memcpy((char*)&a,(char *) &b,sizeof(int));
24 cout << b << endl;
25 }
26 for(int i = 0;i < t; ++i) {
27 cin >> s1;
28 Memcpy(s1,s2,Strlen(s1)+1);
29 cout << s2 << endl;
30 }
31 return 0;
32 }
Input:第一行是整数t,接下来是t个整数,再接下来是t个不带空格的字符串,长度不超过20。
Output:按原样输出t个整数和t个字符串。
Sample Input:
2
12
24
abcd
ef
Sample Output:
12
24
abcd
ef
for(int i=0; i<n; i++)
dest[i] = src[i];
5.指针练习:double
Description:程序填空,使其输出结果是: 1,2,3,4, 10,12,14,16, 18,20,11,12,
1 #include <iostream>
2 using namespace std;
3
4 void Double(int * p, int n)
5 {
6 for(int i = 0;i < n; ++i)
7 p[i] *= 2;
8 }
9
10
11 int main()
12 {
13 int a[3][4] = { { 1,2,3,4},{5,6,7,8},
14 { 9,10,11,12 } };
15
16 Double(
17 // Your Code Here
18 );
19 for(int i = 0;i < 3; ++i) {
20 for(int j = 0; j < 4; ++j)
21 cout << a[i][j] << ",";
22 cout << endl;
23 }
24
25 return 0;
26 }
Input:(无)
Output:
1,2,3,4,
10,12,14,16,
18,20,11,12,
Sample Input:(无)
Sample Output:
1,2,3,4,
10,12,14,16,
18,20,11,12,
a[1], 6
6.指针练习:Memcpy之二
Description:程序填空,使得程序按要求输出。
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4 void Memcpy( void * src, void * dest, int size)
5 {
6 // Your Code Here
7 }
8
9 void Print(int * p,int size)
10 {
11 for(int i = 0;i < size; ++i)
12 cout << p[i] << ",";
13 cout << endl;
14 }
15
16 int main()
17 {
18 int a[10];
19 int n;
20 cin >> n;
21 for(int i = 0;i < n; ++i)
22 cin >> a[i];
23 int b[10] = {0};
24 Memcpy(a,b,sizeof(a));
25 Print(b,n);
26
27 int c[10] = {1,2,3,4,5,6,7,8,9,10};
28 Memcpy(c,c+5,5*sizeof(int)); //将c的前一半拷贝到后一半
29 Print(c,10);
30
31 char s[10] = "123456789";
32 Memcpy(s+2,s+4,5); //将s[2]开始的5个字符拷贝到s[4]开始的地方
33 cout << s << endl;
34
35 strcpy(s, "123456789");
36 Memcpy(s+5,s+1,4); //将s[5]开始的4个字符拷贝到s[1]开始的地方
37 cout << s << endl;
38
39
40 return 0;
41 }
Input:第一行是整数n (1<=n<=10),第二行是 n个整数。
Output:
先原序输出输入数据中的n个整数,然后再输出:
1,2,3,4,5,1,2,3,4,5,
123434567
167896789
Sample Input:
10
15 25 35 45 55 65 75 85 95 105
Sample Output:
15,25,35,45,55,65,75,85,95,105,
1,2,3,4,5,1,2,3,4,5,
123434567
167896789
1 char* csrc = (char*)src;
2 char* cdest = (char*)dest;
3 if(src == dest)
4 return;
5 if(cdest>csrc && cdest<csrc+size) {
6 for(int i=size-1; i>=0; i--)
7 cdest[i] = csrc[i];
8 }
9 else {
10 for(int i=0; i<size; i++)
11 cdest[i] = csrc[i];
12 }
7.指针练习:MyMax
Description:编写一个 MyMax函数,可以用来求任何数组中的最大值 使得程序按要求输出
1 #include <iostream>
2 using namespace std;
3 // Your Code Here
4 int Compare1(void * n1,void * n2)
5 {
6 int * p1 = (int * )n1;
7 int * p2 = (int * )n2;
8 return ((*p1)%10) - ((*p2)%10);
9 }
10 int Compare2(void * n1,void * n2)
11 {
12 int * p1 = (int * )n1;
13 int * p2 = (int * )n2;
14 return *p1 - *p2;
15 }
16 #define eps 1e-6
17 int Compare3(void * n1,void * n2)
18 {
19 float * p1 = (float * )n1;
20 float * p2 = (float * )n2;
21 if( * p1 - * p2 > eps)
22 return 1;
23 else if(* p2 - * p1 > eps)
24 return -1;
25 else
26 return 0;
27 }
28
29 int main()
30 {
31 int t;
32 int a[10];
33 float d[10];
34 cin >> t;
35 while(t--) {
36 int n;
37 cin >> n;
38 for(int i = 0;i < n; ++i)
39 cin >> a[i];
40 for(int i = 0;i < n; ++i)
41 cin >> d[i];
42 int * p = (int *) MyMax(a,sizeof(int),n,Compare1);
43 cout << * p << endl;
44 p = (int *) MyMax(a,sizeof(int),n,Compare2);
45 cout << * p << endl;
46 float * pd = (float * )MyMax(d,sizeof(float),n,Compare3);
47 cout << * pd << endl;
48 }
49 return 0;
50 }
Input:第一行是测试数据组数t,对每组数据:第一行是整数n (1<=n<=10),第2行是n个整数,第3行是n个浮点数。
Output:对每组数据:先输出n个整数中个位数最大的数(答案保证唯一),再输出n个整数中最大的数,再输出n个浮点数中最大的数。
Sample Input:
2
5
31 20 100 7 8
30.1 100.2 2.5 9.8 48.4
2
1 2
0.1 0.2
Sample Output:
8
100
100.2
2
2
0.2
1 void* MyMax(void* a, int width , int num, int (*compare)(void* p1,void* p2))
2 {
3 void* result = a;
4 for(int i=1; i<num; i++) {
5 if(compare(result, ((char*)a)+i*width)<0)
6 result = ((char*)a)+i*width;
7 }
8 return result;
9 }
8.指针练习:指向指针的指针
Description:程序填空使得输出指定结果。
1 #include <iostream>
2 using namespace std;
3 int main()
4 {
5 int x,y,z;
6 x = 10;
7 y = 20;
8 z = 30;
9
10 int * a[3] = { &x, &y,&z};
11 for(
12 // Your Code Here
13 p < a + 3; ++p)
14 cout<< * (*p) << endl;
15 return 0;
16
17 }
Input:(无)
Output:
10
20
30
Sample Input:(无)
Sample Output:
10
20
30
int ** p = a;
9.指针练习:SwapMemory
Description:填写内存交换函数 SwapMemory,使得程序输出指定结果。
1 #include <iostream>
2 using namespace std;
3 void SwapMemory(void * m1,void * m2, int size)
4 {
5 // Your Code Here
6 }
7
8 void PrintIntArray(int * a,int n)
9 {
10 for(int i = 0;i < n; ++i)
11 cout << a[i] << ",";
12 cout << endl;
13 }
14
15 int main()
16 {
17 int a[5] = {1,2,3,4,5};
18 int b[5] = {10,20,30,40,50};
19 SwapMemory(a,b,5 * sizeof(int));
20 PrintIntArray(a,5);
21 PrintIntArray(b,5);
22 char s1[] = "12345";
23 char s2[] = "abcde";
24 SwapMemory(s1,s2,5);
25 cout << s1 << endl;
26 cout << s2 << endl;
27 return 0;
28 }
Input:(无)
Output:
10,20,30,40,50,
1,2,3,4,5,
abcde
12345
Sample Input:(无)
Sample Output:
10,20,30,40,50,
1,2,3,4,5,
abcde
12345
1 char* p1 = (char*)m1;
2 char* p2 = (char*)m2;
3 for(int i=0; i<size; i++) {
4 char tmp = p1[i];
5 p1[i] = p2[i];
6 p2[i] = tmp;
7 }