C/C++ char* arr与char arr[]的区别(反汇编解析)
写作日期:2016.08.31
修改日期:2016.09.01 、2016.09.02。
交流qq:992591601
用了几天时间复习了下C语言。对于C语言的字符串操作有些不习惯,于是作为练习,写下了下面这样错误的程序:
- #include <stdio.h>
- #define MAX_STR_SIZE 100
- void copy_string(char* from, char* to) {
- while (*to++ = *from++);
- }
- void swap_strs(char* str1, char* str2) {
- char tmp[MAX_STR_SIZE];
- copy_string(str1, tmp);
- copy_string(str2, str1);
- copy_string(tmp, str2);
- }
- void sort_strs_by_ascii(char* arr[3]) {
- if (strcmp(arr[0], arr[1]) < 0)
- swap_strs(arr[0], arr[1]);
- if (strcmp(arr[1], arr[2]) < 0)
- swap_strs(arr[1], arr[2]);
- if (strcmp(arr[0], arr[1]) < 0)
- swap_strs(arr[0], arr[1]);
- }
- int main() {
- char* arr[3] = {"dd", "aa", "cc"};
- sort_strs_by_ascii(arr);
- for (int i = 0; i < 3; i++)
- printf("%s\n", arr[i]);
- return 0;
- }
这段程序写得当然不怎么样,主要是为了练习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语言的二级指针。
基本思路就是:
先建立用指针数组,里面每一个指针指向一个字符串数组。再使用二级指针来指向这个指针数组。
这样就构造了一种自制的“二维数组”。达到了我程序想达到的效果。当然这程序只是为了练习,不值一提~
- ##include <stdio.h>
- #define MAX_STR_SIZE 100
- void copy_string(char* from, char* to) {
- while (*to++ = *from++);
- }
- void swap_strs(char* str1, char* str2) {
- char tmp[MAX_STR_SIZE];
- copy_string(str1, tmp);
- copy_string(str2, str1);
- copy_string(tmp, str2);
- }
- void sort_strs_by_ascii(char **p) {
- if (strcmp(*p, *(p + 1)) < 0)
- swap_strs(*p, *(p + 1));
- if (strcmp(*(p + 1), *(p + 2)) < 0)
- swap_strs(*(p + 1), *(p + 2));
- if (strcmp(*p, *(p + 1)) < 0)
- swap_strs(*p, *(p + 1));
- }
- int main() {
- char arr0[] = "aaaaaa";
- char arr1[] = "cccccc";
- char arr2[] = "bbbbbb";
- char* p0 = arr0;
- char* p1 = arr1;
- char* p2 = arr2;
- char* final_arr[3];
- final_arr[0] = p0;
- final_arr[1] = p1;
- final_arr[2] = p2;
- char **p3 = final_arr;
- sort_strs_by_ascii(p3);
- for (int i = 0; i < 3; i++) {
- printf("%s\n", final_arr[i]);
- }
- return 0;
- }

C/C++ char* arr与char arr[]的区别(反汇编解析)的更多相关文章
- char* strcpy( char* dest, const char* src ), int binary_search(int *arr, int key, int n), 可能的实现
#include <stdio.h> char* stringCopy( char* dest, const char* src ) { size_t i = 0; while (dest ...
- char[]数组与char *指针的区别
char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...
- no suitable ctr exists to convert from 'int' to 'std::basic_string<char,std::char_traits<char>,std::allocator<char> >
int xfun(int *a,int n) { int x = *a;//a的类型是int *,a+1跳动一个int的长度 ; pa < a + n; pa++)//指向同一个类型的指针比较大 ...
- C语言执行时报错“表达式必须是可修改的左值,无法从“const char [3]”转换为“char [120]” ”,原因:字符串不能直接赋值
解决该问题的方法:使用strcpy函数进行字符串拷贝 原型声明:char *strcpy(char* dest, const char *src); 头文件:#include <string ...
- 【转】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p
一.可能的组合: (1)const char*p (2)char const*p (3)char *const p(4)const char **p (5)char const**p (6)char ...
- 初始化char指针--赋值和strcpy() 本质区别【转】
原文地址:http://hi.baidu.com/todaygoodhj/item/0500b341bf2832e3bdf45180 使用常量字符串初始化char指针,或者使用strcpy复制,从语法 ...
- char *p 与char p[] 比较
看看下面的程序的输出: #include <stdio.h>char *returnStr(){ char *p="hello world!"; retur ...
- char str[]和char *str的区别
1.http://blog.csdn.net/szchtx/article/details/10396149 char ss[]="C++"; ss[0]='c'; ...
- char *c和char c[]区别
char *c和char c[]区别 问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者 ...
随机推荐
- Windows下 maven3.3.1的安装步骤+maven配置本地仓库
简单讲下maven的安装步骤: 1.在安装maven之前,先确保已经安装JDK1.6及以上版本,并且配置好环境变量. 2.下载maven3,最新版本是Maven3.3.1 ,下载地址:http://m ...
- eclipse的maven项目报Missing artifact jdk.toos:jdk.toos:jar:1.6错
很多框架都会依赖jdk中的tools.jar,但是maven仓库中却没有. 如在eclipse+maven编写mapreduce代码,就会报Missing artifact jdk.toos:jdk. ...
- openjudge2985(数字组合)
描述 有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式.如:n=5,5个数分别为1,2,3,4,5,t=5:那么可能的组合有5=1+4和5=2+3和5=5三种组合方式.输入输入的第一行是两 ...
- CodeForces 743A Vladik and flights (水题)
题意:sb要从a到b,然后要乘坐飞机,只有两家有飞机,如果乘坐同一家的,就免费,如果不是就收到abs(j-i) 的费用,问你最少花费是多少. 析:直接考虑a和b是不是同一家的,如果是,花费为0,如果不 ...
- xml文件格式说明
转载自:http://www.cr173.com/html/10715_1.html 关于xml的有关操作,在读的过程中,由于是初学者有不明白的地方就查资料,发现自己多innerXml,outerXm ...
- 获取基于Internet Explorer_Server的聊天窗口内容
假设在得到窗体中控件的句柄(通过SPY++)的前提下,如果是像文本框这种控件,只要用SendMessage就可得到文本了,但是对于聊天记录窗口却行不通(返回空值),因为那其实是一个内置浏览器Inter ...
- Object-C中动态类型对象相关操作汇总
Object-C(以后简称OC)中有id类型,相对于明确定义类型的静态类型,称为动态类型. 使用动态类型,配合多态(不同类型拥有同名方法),动态绑定(运行时决定实际调用的方法)可以将很多判断延迟到运行 ...
- LIS最长上升子序列O(n^2)与O(nlogn)的算法
动态规划 最长上升子序列问题(LIS).给定n个整数,按从左到右的顺序选出尽量多的整数,组成一个上升子序列(子序列可以理解为:删除0个或多个数,其他数的顺序不变).例如序列1, 6, 2, 3, 7, ...
- Ubuntu下eclipse开发hadoop应用程序环境配置
第一步:下载eclipse-jee-kepler-SR2-linux-gtk-x86_64.tar.gz 注意:如果电脑是64位,就下载linux下的64位eclipse,不要下载32位的eclips ...
- 在mac下svn冲突或其它什么原因无法更新svn副本或是必须要删除svn信息时,如何清除svn信息
find . -type d -name ".svn"|xargs rm -rf 出处: http://blog.csdn.net/springsky_/article/detai ...