指针应该是大家逃避C语言选择Java或者python的一个重要理由吧,最近小编也在学习指针的一些知识,感觉指针确实方便,而且在某些方面确实省时省空间。看了一些算法,对指针有了一定的理解,下面进行一下总结,都是一些基础的算法,但是都很实用哦!
一维数组与指针相结合比较好理解,但是遇到二维数组与指针相结合就相对难理解了,从二维数组入手谈一下指针,二级指针和多级指针。
首先定义对二维数组进行操作的指针变量,用一个题目应用。
- 求N1*N2矩阵中最大的元素极其所在的行和列的位置。
#include<stdio.h>
#define N1 2
#define N2 3
main(){
int a[N1][N2],max,i,j,r,c;
int (*p)[N2]; //定义对二维数组进行操作的指针,要明确列的参数
p = a; //指针p指向数组的首地址
for(i = 0;i < N1;i++)
for(j = 0;j < N2;j++){
scanf("%d",(*(p+i)+j)); //取数组的地址即取指针变量
}
max = **p ; //**p是对*(*(p+0)+0) 的缩写
for(i = 0;i < N1;i++)
for(j = 0;j < N2;j++){
if(max < *(*(p+i)+j)){
max = *(*(p+i)+j);
r = i;
c = j;
}
}
printf("最大值:%d,行:%d,列:%d",max,r,c);
}
不理解的仔细看注释哦!
下面写一下上边的变化形式,用指针p代表二维数组的行。
#include<stdio.h>
#define N1 2
#define N2 3
main(){
int a[N1][N2],max,i,j,r,c;
int (*p)[N2]; //定义对二维数组进行操作的指针,要明确列的参数
p = a; //指针p指向数组的首地址
for(i = 0;i < N1;i++)
for(j = 0;j < N2;j++){
scanf("%d",(*(p+i)+j)); //取数组的地址即取指针变量
}
max = **p ; //**p是对*(*(p+0)+0) 的缩写
for(i = 0;p < a+N1;p++,i++) //注意与上个算法的我区别
for(j = 0;j < N2;j++){
if(max < *(*p + j)){ //*p代表&a[i],即行数的地址!!
max = *(*p + j);
r = i;
c = j;
}
}
printf("最大值:%d,行:%d,列:%d",max,r,c);
}
对需要重点理解的地方进行了标注,注意哦!
- 矩阵的转置
矩阵的转置是而二位数的基础题目,结合指针的形式进行描述。
#include <stdio.h>
main(){
int a[2][3]={1,2,3,4,5,6},b[3][2],i,j;
int (*p)[3];
for(p = a ;p < a+2;p++){
for(j = 0;j < 3;j++){
printf("%6d",*(*p+j));
}
printf("\n");
}
for(i = 0;i < 3;i++){
for(j = 0;j < 2;j++){
*(*(b+i)+j) = *(*(a+j)+i);
printf("%6d",*(*(b+i)+j));
}
printf("\n");
}
}
我们接下来要用字符串数组来介绍一下多级指针,这就需要用到一些字符串相关的函数,下面通过代码的形式就行简单介绍。
- 字符串处理函数
1、字符串长度函数 int strlen(char *s)
#include <stdio.h>
#include <string.h>
main(){
char *s = "Welcome to Tanshan!";
char a[10] = "aaaaaa";
char b[] = "bbbbbbbbb";
char c[40],d;
gets(c);
//strlen函数,传入字符型指针,返回值类型为int
printf("s:%d\n",strlen(s));
printf("a: %d\n",strlen(a));
printf("b:%d\n",strlen(c));
d = strlen("Good!\n");
printf("d: %d\n",d);
}
2、字符串连接函数 char *stract(char *s1,char *s2)
将s2连接到s1之后
#include <stdio.h>
#include <string.h>
main(){
char a[10] = "aaa",*p;
p = "bbb";
strcat(a,p);
printf("a:%s\n",a);
}
3、字符串大小比较函数, int strcmp(chr *s1,char *s2);
用该函数比较两个字符串的ASCII值,若s1大于s2则返回值大于0,若s1小于s2长度,则返回值小于0,若s1和s2相等,则返回值为0;
4、字符串复制函数, char *strcpy(char *s1,char *s2)
将s2的内容全部复制到s1中返回新的字符串指针s1;(s2的长度一定要小于s1)
将两个函数应用于冒泡算法;
- 用冒泡法编写一个程序是8个字符串从小到大排序
#include <stdio.h>
#include <string.h>
main(){
char temp[20],name[8][15];
int i,j,k;
for(i = 0;i < 8 ;i++)
gets(name[i]);
for(i = 0;i < 8-1; i++){
for(j = 0;j < 8-i-1;j++){
if(strcmp(name[j] , name[j+1])>0){
strcpy(temp,name[j]);
strcpy(name[j],name[j+1]);
strcpy(name[j+1],temp);
}
}
}
for(i = 0;i < 8;i++ ){
printf("%s\n",name[i]);
}
}
上边这个算法有些不足之处,二维字符串数组会浪费很大空间,掉因strcpy函数也会进行数组的值的传递也会很浪费时间。这就需要用字符串指针数组来解决这个问题了。
下面用字符串指针数组改良上边的算法:
#include<stdio.h>
#include<string.h>
main(){
char *temp,*a[8] = {"ggggg","sssss","wwwwww","ccccccc","xxxxx","222222","uuuuuu","qqqqqqqq"};
int i,j;
for(i = 0;i < 8-1;i++){
for(j = 0;j < 8-i-1;j++){
if(strcmp(a[j],a[j+1]) > 0){
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(i = 0;i < 8;i++){
printf("%s\n",a[i]);
}
}
上边的的代码可以用多级指针实现,多级指针就是指向指针的指针,指针数组a的每个元素都算指针,定义一个二级指针**p指向指着数组a中的元素。
#include<stdio.h>
#include<string.h>
main(){
char **p,*temp,*a[8] = {"ggggg","sssss","wwwwww","ccccccc","xxxxx","222222","uuuuuu","qqqqqqqq"};
int i,j;
p = a;
for(i = 0;i < 8-1;i++){
for(j = 0;j < 8-i-1;j++){
if(strcmp(a[j],p[j+1]) > 0){
temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}
}
}
for(i = 0;i < 8;i++){
printf("%s\n",*p++);//p的自增运算输出字符;
//printf("%s\n",p[i]);
}
}
基本的指针用法,指针数组的用法,二级指针的用法都介绍给大家了,学习指针的关键要分清“*”
的用法,什么时候取的是地址,什么时候取的是值,要搞清楚,不明白的可以留言哦!