C语言指针快速入门扫盲介绍与简单利用指针对多维数组排序

第一次在网上写技术文章,其实也不是什么复杂的技术,旨在帮助比我还不懂的大学生或是业余编程爱好者,哈哈。

首先关于排序的方法就不多说了,一般学校老师都会告诉我们冒泡排序法选择排序法,百度百科上有详细的解释,两者对我而言都能用,不过我一般是用选择排序法。

好,假定你已经了解了这两种排序法,这时老师布置了作业让你给二维数组排序,怎么办呢?于是你想到用循环嵌套就是了。可是如果是三维数组呢?甚至说六位数组?所以我们可以想象,应该有一个简单统一的方法应对任意维数组吧?没错,答案正是指针,那么废话不多说,我们进入正题吧!

####简单地了解指针,那些年指针与数组不得不说的那些事

如果你点开这篇文章,不难想象阁下一定还未参透指针的奥妙,又或者很有可能你根本就不知道神马是指针!如果真的是这样我强烈建议您购买一本《C Primer Plus》放在案头,作者对指针的讲解事无巨细十分详尽,都是又或者你现在强烈地想快点知道一些有趣的事情,你也可以听我在这里胡说八道,不过一个字一个字慢慢看,你总能看懂。

指针是一种储存变量地址的变量,有两个运算符号,&(查找)和*(解引用)

指针是一种变量(double、integer(int)、double等都是变量的名称),指针的英文是point,就是指向的意思,故不难理解指针变量指向地址。也许你看得云里雾里,不过别急,稍安勿躁。我们都知道我们的计算机是有内存的,当程序运行的时候,程序包括程序当中的数据会被存放到内存里,因此不难想象内存就像一个临时公寓一样,里面每个数据都旅居在一个又一个房间,而且不难想象有的数据日子过得比较精细,住的房子大一点,有的数据过得比较粗糙,房子就小点,最最重要的是他们每个数据住在这里的时候为了方便管理,都有一个门牌号,而我们的指针类型的变量便可以用来储存数据的门牌号,或者更准确地说,地址,哈哈!我想你现在也许好像有点明白又不太明白指针是神马意思,或者说你不太明白指针究竟可以干嘛!

好,我们来上一段代码,编个函数,方便我们交换两个变量的数值。

#include<stdio.h> 
void change(int a,int b) 
{  
  int c=a;  
  a=b;  
  b=c;
}  
int main(void)  
{  
  int a=3,b=4;  
  change(a,b);  
  printf("a=%d,b=%d\n",a,b);  
  return 0;  
}  

然后我们不难发现——这个函数完全没有用!这是怎么回事呢?这是因为函数change(int a,int b)在进行调用的时候,我们只是传递了a和b的值给change(int a,int b)中的a和b,相当于我们只是把“临时公寓”里面的数据(更准确的说是变量)的照片交给了change(int a,int b),因此是无法修改我们的变量的数值的!但是如果我们把数据的“门牌号”告诉我们的函数呢?这时指针的一个很重要的功能便可以发挥价值了——利用指针在函数间进行通信

我们再来看一段代码。

#include<stdio.h>
void change(int *a,int *b)
//int *a代表a是int类型的指针
{
  int c=*a;
  *a=*b;
  *b=c;
}
int main(void)
{
  int a=3,b=4;
  change(&a,&b); 
  //&a的意思是查找a的地址,或者说&a代表a的地址
  printf("a=%d,b=%d\n",a,b);
  return 0; //一个小小的好习惯,也许不加也没事,但是加上为妙
}

运行一遍后发现函数有用了!这就是利用指针在函数间进行通信

看到现在,也许你对指针有了一个基本的认识:指针便是指向变量数据地址的变量,利用这个地址我们可以直接去访问、修改某个变量的值,不管它是不是全局变量,我们在任何一个函数中都可以访问它。下面我们再强调一下一些指针的基本操作。

/*一、如何声明指针变量*/
int *a,*b; //声明了a、b两个int类型的指针
int *a, b; //a是指针,b不是指针
char *a; //声明了char类型的指针a

/****************************************/

/*二、给指针变量赋值*/
int a; int *b=&a; //&为查找符号,查找b的地址
int a; int *b=&a; int *c=*b
//可以令一个指针变量等于另一个指针变量
//有很多同学会直接用c++的文件来运行c的代码,需要注意在c++里面如果将一个指针变量赋给另一个不同类型的指针变量的话需要强制转换一下,例如int *a=&b; double *c=&d; a=(int *)c;

/****************************************/

/*三、解引用*/
//没错,在声明指针的时候要用*,引用的时候还是*
//具体解引用是什么意思请看下面演示
char a='2';
char *point=&a;
putchar(*point); //屏幕上面会输出2
*a++;
putchar(*point); //屏幕上面会输出3
*a='m'+1;
printf("%c",*a); //屏幕上面会输出n

/****************************************/

/*四、打印输出出地址试试看会是怎样*/
int b; int *a=&b;
printf("%p,%p",&b,a);
//%p指的是a是指针(point),&b等同于a,*a等同于b
//输出结果应当是两个相等的十六进制数
//例如0022FEB8,0022FEB8
//此处建议在网上了解一下十六进制数的表示法则,我们是用十六进制数来表示内存地址的

/****************************************/

/*五、指针的一些值得知道的事情*/

int b;int *a=&b;
printf("%p,%p",a,a+1);
//如果屏幕显示出0022FEB8,那么紧接着的一定是0022FEBC
//因为地址是以十六进制表示的,a+1意味着0022FEB8,如何理解呢?
//因为a是int型指针,int型变量占4个字节
//因此如果说a(a=0022FEB8)代表着a的住址,那么a+1便可以粗略地理解为代表下一个变量的住址
//之所以要加上4,是因为在内存中这4个字节都属于(int *)a,下面我们画个图来理解一下

/****************************************/

C语言指针快速入门扫盲介绍与简单利用指针对多维数组排序_第1张图片

####如果你理解了这个表格,那么我们便可以了解数组和指针之间紧密的联系了
我们刚刚已经试验过,在函数之间,仅仅靠变量的名称是无法通信的,但是数组却恰恰不一样。下面看一段代码:

#include <stdio.h>
void strarray(char a[])
{
  a[0]='O';
  a[1]='K';
}
void test(char a)
{
  a='?';
}
int main(void)
{
  char a[4]={'H','i','!',0};
  puts(a);//输出的是"Hi!"
  strarray(a);
  puts(a);//输出的是"OK!"
  test(a[2])
  puts(a);//输出的依然是"OK!"
  return 0;
}

为什么数组可以不用指针就可以在函数间通信呢?原因就是数组名称就是指针,也就是说&a[0]==a,我们往函数里面传递的是地址,即我们将a[0]的地址传递给了void strarray(char a[])。

#include<stdio.h>
#include<string.h>
int main(void)
{
  int a[0];
  printf("%p,%p\n",a,&a[0]);
  return 0;
} 

知道了这些以后我们就可以利用指针对多维数组进行方便地排序啦!
可以理解对于三维数组a[3][3][3],*a==a[0][0],*(a+1)==a[0][1],*(a+3)==a[1][0]……

#include <stdio.h>
int main(void)
{
  int a[][]={{9,8,7},{6,5,4}},i=0,m,temp;
  for(;i<5;i++)
  {
    for(m=0;m<5;m++)
    {
      if(*(a+m)>*(a+m+1))
      {
        temp=*(a+m);
        *(a+m)=*(a+m+1);
        *(a+m+1)=temp;
      }
    }
  }
  return 0;
}

文笔粗糙,写得也不严谨,大家看看就好,谢谢你能够看到这里,如果不懂,最好是去看书(例如《C Primer Plus》《C程序设计》),或者也可以问老师,另外以上代码没事可以自己敲一敲,然后就懂了。

你可能感兴趣的:(C语言基础知识)