写作日期:2016.08.31

修改日期:2016.09.01 、2016.09.02。

交流qq:992591601

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

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

这段程序写得当然不怎么样,主要是为了练习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语言的二级指针。

基本思路就是:

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

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

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

最新文章

  1. Elasticsearch Span Query跨度查询
  2. HDU 4942 Game on S♂play(线段树、模拟、扩栈)
  3. POJ 1830 开关问题 (高斯消元)
  4. 注入器和发布库--AngularJS学习笔记(三)
  5. 20145215《Java程序设计》第4周学习总结
  6. EGO Refresh小总结
  7. jQuery:使用$获取对象后检查该对象是否存在
  8. Yarn通信过程
  9. DNS 和 IPv6 配置攻略
  10. 你想建设一个能承受500万PV/每天的网站吗?如果计算呢?(转)
  11. hashlib模块--摘要算法
  12. PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
  13. OpenCV3编程入门读书笔记5-边缘检测
  14. 对XML里的属性或元素进行模糊搜索的方法
  15. 对于在git上面拉代码报&quot;error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054&quot;解决方法
  16. HDU 1046(最短路径 **)
  17. java freemarker导出word时添加或勾选复选框
  18. [luogu3979][bzoj3083]遥远的国度
  19. TensorFlow训练MNIST数据集(3) —— 卷积神经网络
  20. shell中$#等含义

热门文章

  1. 流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)
  2. Socket通信基本原理
  3. 转:Xms Xmx PermSize MaxPermSize 区别
  4. webDriver环境搭建与测试
  5. linux下的基本操作
  6. spring事物传播机制与隔离级别
  7. 二叉搜索树、B树
  8. chrome 浏览器 手动同步书签 && 安装离线插件
  9. WEB响应布局
  10. Linux下VirtualBox启动物理硬盘上已安装的Window 8系统