指针 例题解析
例题1.函数fun的功能是交换x 和y 中的值,且通过正确调用返回交换结果
func (int *x,int *y) { int temp; temp=*x; *x=*y; *y=temp;} fund (int *x,int *y) { *x=*x+*y; *y=*x-*y; *x=*x-*y; } fune (int *x, int *y) { *x=*x^*y; *y=*y^*x; *x=*x^*y;}
例题2.下列函数功能:
compare(char *s, char *t) { while ( (*s) && (*t) && (*t++ == *s++) );////为什么函数调用是错误的 return (*s - *t); }
循环条件( (*s) && (*t) && (*t++==*s++) );表示:
*s不为0 并且 *t不为0 并且 当前t指向的字符和s指向的字符相等时继续循环
所以退出循环时只有三种情况,
1. *s已经指向了字符串尾
2. *t已经指向了字符串尾
3. *s与*t不相等
所以若两个初始字符串s与t中s大于t返回正数,s等于t返回0, s小于t返回负数.
因为“&”和“*”两个运算符的优先级相同,按自右而左的方向结合,所以*&j运算先进行&j运算,得j的地址,再进行*运算,取所得地址里面的值,故*&j与j等价。
例题3.
int a[2][3]={1,2,3,4,5,6};
int m,*ptr;
ptr=&a[0][0];
m=(*ptr) * (*(ptr+2)) * (*(ptr+4));
printf("%d\n",m);
ptr是整个数组的首地址,那么*ptr=a[0][0]是无可争议滴!,接着ptr+2,很明显是a[0][2]的地址,因为二维数组在存储的时候是线性存储的,不存在二维,仅仅是逻辑上的二维而已,那么ptr+4其实就是从a[0][0]之后数四个数,那么就得到其是a[1][1]的地址,即是5的地址。ptr+2表示指针向后移2,即ptr+2=&a[0][2];则*(ptr+2)=a[0][2]=3;同理ptr+4表示指针向后移4,即ptr+4=&a[1][1];则*(ptr+4)=a[1][1]=5;所以m=(*ptr)*(*(ptr+2))*(*(ptr+4))=1*3*5=15。
例题4.
#include<stdio.h> #include<iostream> void fun(int *a, int *b, int *c) { int *temp; temp = a; a = b; b = temp;//交换a b地址 printf("%p %p %p\n", a, b, c); *temp = *b; *b = *c; *c = *temp; } void main() { int a, b, c, *p1, *p2, *p3; a = 5; b = 7; c = 3; p1 = &a; p2 = &b; p3 = &c; printf("%p %p %p\n", &a, &b, &c); fun(p1, p2, p3); printf("%d,%d,%d\n", a, b, c);// 3 7 3 std::cin.get(); }
交换 a b的地址后,temp里存储的是变量a的地址。*temp = *b,此时*temp = 5; *b = *c 此时变量a的地址里的值是*c的值 3 即*temp的值是3。
例题5.
static int a[2][3]={1,3,5,2,4,6}; int * add[2][3]={*a,*a+1,*a+2,*(a+1),*(a+1)+1,*(a+1)+2}; int **p,i; p=add[0]; for(i=0;i<6;i++) { printf("%d ",**p); p++;} printf("\n");
int * add[2][3] 是一个二维数组,数组元素是int * a+1表示第一行首地址 *a + 1 = *(a + 0)+ 1表示第0行第一列元素地址
*(a+1) = *(a + 1) + 0表示第一行第零列元素地址
对于二维数组名a和*a,二者的区别在于类型不同。
对于TYPE a[M][N];当使用a时,可以等同于二级指针TYPE **型。而使用*a时,等同于TYPE*型。
从概念上说,a表示二维数组a的首地址,而*a表示二维数组a第一行a[0]的首地址。
这样在使用的时候就有所区别。比如 对a的操作a[4]表示a的第四行首地址,而对*a的操作(*a)[4]则代表第一行的第4个元素,即a[0][4]。
所以a和*a除了值相同外,其它的各方面都是不同的。
例题6.输入四个整数,按由小到大的顺序输出。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void swap(int *a, int *b) { *a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b; } void main() { int a, b, c, d; printf("input four data:\n"); scanf("%d%d%d%d", &a, &b, &c, &d); printf("before:a = %d,b = %d,c = %d ,d = %d\n", a, b, c, d); if (a > b) swap(&a, &b); if (a > c) swap(&a, &c); if (a > d) swap(&a, &d); if (b > c) swap(&b, &c); if (b > d) swap(&b, &d); if (c > d) swap(&c, &d); printf("after:a = %d,b = %d,c = %d,d = %d\n", a, b, c, d); system("pause"); }
例题7.写一函数,将一个3×3的矩阵转置。
#include <stdio.h> #include <stdlib.h> void main() { int a[3][3]; int b[3][3]; for (int i = 0; i<3; i++) { for (int j = 0; j<3; j++) { a[i][j] = rand() % 100; printf("%d\t", a[i][j]); } printf("\n"); } printf("\n"); for (int i = 0; i < 3; i++)//转置矩阵1 for (int j = i + 1; j < 3; j++) { int temp; temp = a[i][j]; a[i][j] = a[j][i]; a[j][i] = temp; } for (int i = 0; i < 3; i++)//转置矩阵2 for (int j = 0; j < 3; j++) { b[j][i] = a[i][j]; //b[i][j] = a[j][i]也行 } for (int i = 0; i<3; i++)//重新输出 { for (int j = 0; j<3; j++) { printf("%d\t", b[i][j]); } printf("\n"); } system("pause"); }
例题8.编一程序,打入月份号,输出该月的英文月名。例如,输入"3",则输出"March",要求用指针数组处理。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> void main() { int i; char *a[12] = { "January","February","March","April","May","June","July","August","September","October","November","December" }; printf("输入月份号:"); scanf("%d", &i); printf("%s\n", a[i - 1]); system("pause"); }
例题9.写一函数完成将无符号十进制整数转换成十六进制字符表示并存于字符串数组中
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void itoh(unsigned int num, char *hex) { int mod; int arr[32] = { 0 }; int i = 0, j = 0; int m; char Hexadecimal[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; while (num > 0) { mod = num % 16; arr[i++] = mod; num = num / 16; } for (i = i - 1; i >= 0; i--) { m = arr[i]; hex[j++] = Hexadecimal[m]; } } void main() { int num; scanf("%d", &num); char Hex[10] = { 0 }; itoh(num, Hex); printf("转换后的16进制数为:"); for (int i = 0; i < 11; i++) printf("%c", Hex[i]); system("pause"); }
例题10.写一函数完成将无符号十进制整数转换成十六进制字符表示并存于字符串数组中。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void itoh(unsigned int num, char *hex) { int mod; int arr[32] = { 0 }; int i = 0, j = 0; int m; char Hexadecimal[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; while (num > 0) { mod = num % 16; arr[i++] = mod; num = num / 16; } for (i = i - 1; i >= 0; i--) { m = arr[i]; hex[j++] = Hexadecimal[m]; } } void main() { int num; scanf("%d", &num); char Hex[10] = { 0 }; itoh(num, Hex); printf("转换后的16进制数为:"); for (int i = 0; i < 11; i++) printf("%c", Hex[i]); system("pause"); }
11.10进制转二进制。 八进制换数即可
#include<stdio.h> #include<stdlib.h> void itb(int num) { if (num == 0) return; else { itb(num / 2); printf("%d", num % 2); //此printf函数在递归(函数)调用的上面是逆序输出二进制 } //此printf函数在递归(函数)调用的下面是顺序输出二进制 } void main() { printf("输入你要转换的十进制数:"); int num; scanf_s("%d", &num); printf("\n转换后的二进制数是:\n"); itb(num); system("pause"); }