linux c /指针数组的使用及字符串排序


最近为了做一题字符串排序的题目,花了我不少时间,现在把它记下来,作为学习笔记吧
首先要知道什么是指针数组?
指针数组:是一个存放指针的数组,数组的每个元素都是一个指针。
注意:要与数组指针区分开来,数组指针是指向数组的指针。
举个列子:
char *arr[5];//它是一个存放有5个指针,每个指针都指向一个字符串的数组

下面举个简单的例程:

char *k[2];
char *q[2] = {"abc","345"};
    
printf("addk:%p,addq0:%p,addq1:%p\n", k[0], q[0],q[1]);//查看初始时三个指针的值

k[0] = q[0];
printf("addk:%p,addq0:%p,addq1:%p\n", k[0], q[0],q[1]);//下面依次查看交换后三个指针的值

q[0] = q[1];
printf("addk:%p,addq0:%p,addq1:%p\n", k[0], q[0],q[1]);

q[1] = k[0];
printf("addk:%p,addq0:%p,addq1:%p\n", k[0], q[0],q[1]);
printf("q0:%s\nq1:%s\n", q[0], q[1]);//打印指针数组交换后的值

如上程序,当执行 k[0] = q[0]; 后 k[0] 的值发生了改变,即指针k[0]的值和 q[0]的值相同,这样他们指向的地址都是字符串 “abc” 的地址,所以 k[0] = q[0]; 执行的结果是地址的赋值和改变,而非地址所指向的内存存放的数值的赋值和改变。

如果执行下面的语句,编译时不一定会报错,但是执行会出错:

函数执行的是对字符串的拷贝,而非地址的赋值,但是如果 k[0] 和 q[0] 都是对应的二维数组的地址话则是可以正常赋值的

strcpy(k[0],"aaa")//这样也是不行的,strcpy 只能对单纯的数组进行操作
q[0] = "ccc";//这样是可以的
 
  

如果对指针数组单独赋字符串则是可以的如:

下面贴一下我的字符串转换的代码:

#include  //预定义与宏定义 
#include  
#define LEN 5
#define WIDE 5

void sortlist(char *string[], int num); //函数的声明
void printlist(char *string[], int num);

int main(){ //主函数

        int i = 0;
        char *str[LEN] = {"dbcd", "aacd", "bace", "esae", "aede" };//要比较的字符串

        for(i = 0; i < LEN; i++){ //先打印出要显示的字符串
    
                printf("%s\t",str[i]);
        }   
        printf("\n");

        sortlist(str, LEN); //从小到大的排序
        printlist(str, LEN); //打印出排序后的字符串
    
        return 0;
}

void sortlist(char *string[], int num){ //排序函数体

        char *temp;
        int i = 0;
        int j = 0;
    
        for(i = 0; i < num-1; i++){ //使用冒泡排序法
     
                for(j = 0; j < num-1 ; j++){ 

                        if(strcmp(string[j],string[j+1]) == 1){ //用字符串比较函数进行比较两个字符串
    
                                temp        = string[j];//进行地址交换
                                string[j]   = string[j+1];
                                string[j+1] = temp;
                        }
                }
        }
}
void printlist(char *string[], int num){ //打印函数体


        int i = 0;
        for(i = 0; i < num; i++){

                printf("%s\t",string[i]);
        }
        printf("\n");
}
//执行结果
dbcd    aacd    bace    esae    aede//要排序的字符串
aacd    aede    bace    dbcd    esae//排序后的字符串

好了下面讲一个有意思的程序:

#include 
void swap(int *ap, int *bp);
int main(){

        int a = 10; 
        int b = 20; 
    
        int *ap,*bp;
        ap = &a; 
        bp = &b;    

        printf("a:%d , b:%d\n" , a , b);
        printf("ap:%p , bp:%p\n", ap , bp);

        swap(ap, bp);
    
        printf("a:%d , b:%d\n", a , b);
        printf("ap:%p , bp:%p\n", ap , bp);
        return 0;
}
void swap(int *ap, int *bp){

        int *n; 

//      int *_ap , *_bp;
//      _ap = a;        
//      _bp = b;

//      n   = _ap;      
//      _ap = _bp;
//      _bp = n;

        n  = ap; 
        ap = bp;    
        bp = n;
        printf("swap_ap:%p , swap_bp:%p\n", ap , bp);
        printf("swap_a:%d , swap_b:%d\n", *ap, *bp);
}

//执行结果如下
main_a:10,main_b:20                     //未交换前的值
main_ap:0xbff9c31c,main_bp:0xbff9c318   //未交换前的定义的两个指针
swap_ap:0xbff9c318,swap_bp:0xbff9c31c   //交换函数中指针交换后的值,可以看到函数中地址是有交换的
swap_a:20,swap_b:10                     //交换函数中a和b的值,a和b的值也是有交换的
main_a:10,main_b:20                     //交换后main函数中a和b的值,很显然a和b的值并没有交换
main_ap:0xbff9c31c,main_bp:0xbff9c318   //相应的地址也没有改变


为什么?

在执行交换函数时,传递到函数中的形参在函数中进行了一份拷贝,之后所有的操作都是对拷贝进行的,如上面的注释部分:

      int *_ap , *_bp;


   _ap  =   a;        
      _bp   =   b;

          n  =  _ap;         

 _ap  =  _bp;

_bp   =  n;

a   =  _ap;

  b   =  _bp;

当结束交换函数时,函数中的变量被释放,所以并没有交换主函数中a和b的地址。

那么为什么用字符数组却可以呢?

首先看一个这样的例程:

#include 
void swap(int **ap, int **bp);
int main(){

        int a = 10; 
        int b = 20; 
    
        int *ap,*bp;
        ap = &a; 
        bp = &b;    

        printf("main_a:%d,main_b:%d\n",a,b);
        printf("main_ap:%p,main_bp:%p\n",ap,bp);

        swap(&ap, &bp);
    
        printf("main_a:%d,main_b:%d\n",a,b);
        printf("main_*ap:%d,main_*bp:%d\n",*ap,*bp);
        printf("main_ap:%p,main_bp:%p\n",ap,bp);
        return 0;
}

void swap(int **ap, int **bp){

        int *n;

         n  = *ap;
        *ap = *bp;    
        *bp = n;

        printf("swap_ap:%p,swap_bp:%p\n",*ap,*bp);
        printf("swap_a:%d,swap_b:%d\n",**ap,**bp);
}

//函数的执行结果如下
main_a:10,main_b:20
main_ap:0xbf9ffc3c,main_bp:0xbf9ffc38

swap_ap:0xbf9ffc38,swap_bp:0xbf9ffc3c
swap_a:20,swap_b:10

main_a:10,main_b:20                     
main_*ap:20,main_*bp:10                 //主函数中的指针所指向的值交换了
main_ap:0xbf9ffc38,main_bp:0xbf9ffc3c   //指针的地址变化了


用上面这个函数替换上面的swap函数,可以成功实现a和b值的交换。

注意:这里看到的a和b值的交换是用指针进行观察的,而a和b的原值是不会被改变的,因为它们都是局部变量。其实也就是说改变的是指针的值,即地址。

上面的函数就解释了为什么指针数组可以实现交换,因为使用指针数组时,传递给swap函数的是指向指针的指针,对指针数组的操作就是对指针指向的指针的操作。

文章不是很完善,后期可能会有修改。






你可能感兴趣的:(linux,c)