C语言指针搞不懂?看看这些算法吧!

指针应该是大家逃避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]);
	}
}

基本的指针用法,指针数组的用法,二级指针的用法都介绍给大家了,学习指针的关键要分清“*”的用法,什么时候取的是地址,什么时候取的是值,要搞清楚,不明白的可以留言哦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值