C/C++ char* arr与char arr[]的区别(反汇编解析)

写作日期:2016.08.31

修改日期:2016.09.01 、2016.09.02。

交流qq:992591601

 

用了几天时间复习了下C语言。对于C语言的字符串操作有些不习惯,于是作为练习,写下了下面这样错误的程序:

 

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2.   
  3. #define MAX_STR_SIZE 100  
  4.   
  5. void copy_string(char* from, char* to) {  
  6.     while (*to++ = *from++);  
  7. }  
  8.   
  9. void swap_strs(char* str1, char* str2) {  
  10.     char tmp[MAX_STR_SIZE];  
  11.     copy_string(str1, tmp);  
  12.     copy_string(str2, str1);  
  13.     copy_string(tmp, str2);  
  14. }  
  15.   
  16. void sort_strs_by_ascii(char* arr[3]) {  
  17.     if (strcmp(arr[0], arr[1]) < 0)  
  18.         swap_strs(arr[0], arr[1]);  
  19.     if (strcmp(arr[1], arr[2]) < 0)  
  20.         swap_strs(arr[1], arr[2]);  
  21.     if (strcmp(arr[0], arr[1]) < 0)  
  22.         swap_strs(arr[0], arr[1]);  
  23. }  
  24.   
  25. int main() {  
  26.     char* arr[3] = {"dd", "aa", "cc"};  
  27.     sort_strs_by_ascii(arr);  
  28.     for (int i = 0; i < 3; i++)   
  29.         printf("%s\n", arr[i]);  
  30.     return 0;  
  31. }  

 

 

这段程序写得当然不怎么样,主要是为了练习C语言,特意去使用一些东西,例如C字符串指针的,指针数组。

程序中的数组的中存放三个字符串指针。将该数组作为参数来通过sort_strs_by_ascii方法排序。但在字符串操作过程中报错。

 

之后我才了解,char* arr这样的字符串指针,指向的值是存放在常量区的,不可改写。但该指针可以随意指向其它的地址空间。

而char arr[]这样的数组指针虽然本质也是指针,指针指向的内容却是固定在数组的内存空间的。但该数组空间里的内容是可以改写的。

 

接下来,我也大言不惭地用反汇编技术来解释下char* arr和char arr[]的区别。

截图部分第一个白色框是char arr[]初始化对应的汇编语句,可以清晰看到其过程。首先字符串本身是在静态区。白框的语句是三个赋值过程,将静态区0x00D95858地址的内容赋给arr数组地址。所以并不是仅仅让arr指针指向0x00D95858。而是实实在在地将该地址的内容赋过来。因为字符串比较短,所以编译器编译的汇编语言是三个赋值语句,如果是很长的字符串,这个过程一定是循环。

第二个白框是,char* arr的过程,很简单,就是指向静态区对应的字符串地址就好了。

所以可以知道,不管哪种方式,xxx = "abcd",便意味着字符串赋值操作,C语言就会首先在静态区分配内存存储该字符串。接下来,采用char arr[] 或char* arr,则各有各的方式。

 

为了解决上面那个程序,使用了C语言的二级指针。

基本思路就是:

                      先建立用指针数组,里面每一个指针指向一个字符串数组。再使用二级指针来指向这个指针数组。

                      这样就构造了一种自制的“二维数组”。达到了我程序想达到的效果。当然这程序只是为了练习,不值一提~

 

[cpp] view plain copy
 
  1. ##include <stdio.h>  
  2.   
  3. #define MAX_STR_SIZE 100  
  4.   
  5. void copy_string(char* from, char* to) {  
  6.     while (*to++ = *from++);  
  7. }  
  8.   
  9. void swap_strs(char* str1, char* str2) {  
  10.     char tmp[MAX_STR_SIZE];  
  11.     copy_string(str1, tmp);  
  12.     copy_string(str2, str1);  
  13.     copy_string(tmp, str2);  
  14. }  
  15.   
  16. void sort_strs_by_ascii(char **p) {  
  17.     if (strcmp(*p, *(p + 1)) < 0)  
  18.         swap_strs(*p, *(p + 1));  
  19.     if (strcmp(*(p + 1), *(p + 2)) < 0)  
  20.         swap_strs(*(p + 1), *(p + 2));  
  21.     if (strcmp(*p, *(p + 1)) < 0)  
  22.         swap_strs(*p, *(p + 1));  
  23. }  
  24.   
  25. int main() {  
  26.     char arr0[] = "aaaaaa";  
  27.     char arr1[] = "cccccc";  
  28.     char arr2[] = "bbbbbb";  
  29.     char* p0 = arr0;  
  30.     char* p1 = arr1;  
  31.     char* p2 = arr2;  
  32.     char* final_arr[3];  
  33.     final_arr[0] = p0;  
  34.     final_arr[1] = p1;  
  35.     final_arr[2] = p2;  
  36.     char **p3 = final_arr;  
  37.     sort_strs_by_ascii(p3);  
  38.     for (int i = 0; i < 3; i++) {  
  39.         printf("%s\n", final_arr[i]);  
  40.     }  
  41.     return 0;  
  42. }  

posted on 2016-08-31 21:18  J·Marcus  阅读(2489)  评论(0编辑  收藏  举报

导航