zoukankan      html  css  js  c++  java
  • 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 ", 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 ", final_arr[i]);  
    40.     }  
    41.     return 0;  
    42. }  
  • 相关阅读:
    c# Exception 异常信息归整
    解决PKIX(PKIX path building failed) 问题 unable to find valid certification path to requested target
    java Thumbnails 加载网络图片,处理返回base64
    C# 解析 Json
    mysql 中文乱码解决方法
    .Net WinForm下配置Log4Net(总结不输出原因)
    uploadify 后台动态传参数
    C# rename方法重命名文件
    将Qt5.5 动态链接生成的exe及依赖dll打包方法
    远程桌面Default.rdp 中各个参数的含义(转)
  • 原文地址:https://www.cnblogs.com/rixiang/p/5827606.html
Copyright © 2011-2022 走看看