C指针思考-(1)
首先记录下时间吧,@2016-08-18 23:26:22,这段时间看了同事的3本经典的书,《c缺陷和陷阱》,《c和指针》和《c专家编程》,感觉指针说的最多,多多少少还是有点领悟,记录下自己对指针的心得吧。
1.很多时候多说指针和数组是等效的。这句话是有条件的,由于最近在看c++方面的资料(c现在工作不好找啊),有了新的理解。
简单的来说,指针是一个间接寻址,而数组是直接寻址,在内存中,指针需要去一次地址后才能取到数据,而数组在内存中就是地址,直接根据地址就可以取到数据。所以在作为参数传递到函数中时,带入指针和带入数组,这个是等价的,因为传入的都是地址。这里我仔细想了想,某种意义上,指针也是传值操作,只不过类型是一个TYPE *而已,传入的是指向的那个地址(p的内容,也就是p的指向,也就是数据的地址,这里指针可以有很多理解,每段时间的理解都不一样,反正就是一个变量,存的是一个数据块的地址,指针根据这个地址去取数据)。
2.看高质量的c及c++编程指南--指针参数是如何传递内存的,这个好纠结,真的好纠结,我看完了,还是不敢说自己完全理解,只能记录自己理解的部分。
首先一个二级指针的描述吧
pp --> p --> data in Mem
char *p = NULL;
p = (char *) malloc(10);
char **pp = NULL;
pp = &p;
其次是一个传值与传地址的理解吧,传值就是数据一个copy,传址就是变量在内存中地址传进去,很明显,可以改变地址里的内容,因而传指针和传数组都是能够改变传入的值的。
#include <stdio.h> void InPt(char *p)
{
printf("InPt p=[%s]\t *p=[%c] \t &p = [%d]\n", p, *p, &p);
} void InArr(char p[])
{
printf("InArr p=[%d]\t p[0]=[%c] \t &p[0] = [%d]\n", p, p[0], &p[0]);
}
int main(void)
{
printf("Hello World!\n"); char *p1 = "test";//这个是指向常量,分配在静态数据区,妄图改变是不可行的。
//*p1 = 'C'; error here char arr[5]= "this";
char *p = arr;
printf("Main InArr arr=[%d]\t arr[0]=[%c] \t &arr[0] = [%d]\n", arr, arr[0], &arr[0]);
printf("Main InPt p=[%s]\t *p=[%c] \t &p = [%d]\n", p, *p, &p); printf("*****\n");
InArr(arr);
InPt(p); printf("%s\n", p); return 0;
}
/*************Result:****************/
Hello World!
Main InArr arr=[2752167] arr[0]=[t] &arr[0] = [2752167]
Main InPt p=[this] *p=[t] &p = [2752160]
*****
InArr p=[2752167] p[0]=[t] &p[0] = [2752167]
InPt p=[this] *p=[t] &p = [2752144]
this
/*************end:****************/
可以看到 &p = [2752160] &p = [2752160] 带进去的值是一样,但是装这个值的盒子(内存)却不一样,因为编译器为函数的参数制作值copy,所以我理解,传指针和传数组都是传‘值’,只不过这个值特殊而已,是一个地址而已。
林博士在《高质量的c及c++编程指南》举得例子:
void GetMemory(char *p, int num)
{
p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
char *str = NULL;
GetMemory(str, 100); // str 仍然为 NULL
strcpy(str, "hello"); // 运行错误
}
分析下GetMemory(str, 100)中str是一个指针,指针是间接取值,自身也占4个字节的空间,所以Test中的&str和GetMemory中的&p是两个盒子,只不过两个盒子中的东西一样而已,这某种意义上是传值,传的是盒子里的内容,指针这里很容易弄乱,至少我是这样的。其返回的任然是装指针的那个盒子,而这盒子并不是和主函数中的盒子一样,所以,分配不成功。
解决方法1:书中的一个是二级指针,带入chap **p,这样的话把盒子的地址传进去,在带出来.一级p指向data,其地址是二级p的内容,很明显二级就是传的一级指针的地址。
方法2:返回值传递动态内存
char *GetMemory3(int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}
void Test3(void)
{
char *str = NULL;
str = GetMemory3(100);
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
在堆上申请一块地址,p指向其,并返回p的地址。而后str指向这块地址,ok。
好了睡觉去。
C指针思考-(1)的更多相关文章
- C++ 风格与技术 FAQ(中文版)
Bjarne Stroustrup 的 C++ 风格与技术 FAQ(中文版) 原作:Bjarne Stroustrup 翻译:Antigloss 译者的话:尽管我已非常用心,力求完美,但受水平所 ...
- [BS-21] 关于OC中对象与指针的思考
关于OC中对象与指针的思考 1. 创建对象: OC中可通过代码Person *p = [[Person alloc] init];创建了一个对象p.该过程中内存情况为: 在当前线程的栈(默认1M)中, ...
- java中传值及引伸深度克隆的思考(说白了Java只能传递对象指针)
java中传值及引伸深度克隆的思考 大家都知道java中没有指针.难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址的话简直不可想象! java中内存的分配方式有两种,一种是在堆中分配, ...
- C++树的插入和遍历(关于指针的指针,指针的引用的思考)
题目 写一个树的插入和遍历的算法,插入时按照单词的字典顺序排序(左边放比它"小"的单词,右边放比它"大"的单词),对重复插入的单词进行计数. 程序源码 #inc ...
- 【C】对指针表达式的个人总结与思考
本文内容参考<c 和 指针>. 声明:本博文只为那些能沉得住气,认真研究,探索真知的人参考,浮躁的人请离开,因为看不懂. 感觉以前学c的时候,学的指针真是白学了,今天看到这个内容,困惑后, ...
- c++中函数中变量内存分配以及返回指针、引用类型的思考
众所周知,我们在编程的时候经常会在函数中声明局部变量(包括普通类型的变量.指针.引用等等). 同时,为了满足程序功能的需要,函数的返回值也经常是指针类型或是引用类型,而这返回的指针或是引用也经常指向函 ...
- 二叉搜索树的实现及指针问题的一点思考(C++)
今天实现二叉搜索树的时候因为指针的问题卡了一上午(实在不应该...),一直segmentation fault,个人感觉还是需要记录一下的. 首先贴一下做的题的意思: 输入一系列整数,建立二叉排序数, ...
- 由strcat函数引发的C语言中数组和指针问题的思考
问题一 首先,来看一下下面这段代码: #include <stdio.h> #include <string.h> int main() { char *str = " ...
- C++ Primer 学习笔记与思考_7 void和void*指针的使用方法
(一)void的含义 void的字面意思是"无类型",void差点儿仅仅有"凝视"和限制程序的作用,由于从来没有人会定义一个void变量,让我们试着来定义: v ...
随机推荐
- JSP获取json格式的数据报错 Uncaught SyntaxError: Unexpected identifier
后台json字符串是 {"id":"cmdb_ci.`fully_qualified_domain_name`","field":" ...
- UVA272-TEX Quotes(紫书例题3.1)
TeX is a typesetting language developed by Donald Knuth. It takes source text together with a few ty ...
- sql删除注意的问题
老大骂你都是有原因的,基础要打好!!!! SQL关于删除的三个语句:DROP.TRUNCATE. DELETE 的区别. DROP test; 删除表test,并释放空间,将test表删除的一干二净 ...
- COJS 1752. [BOI2007]摩基亚Mokia
1752. [BOI2007]摩基亚Mokia ★★★ 输入文件:mokia.in 输出文件:mokia.out 简单对比时间限制:5 s 内存限制:128 MB [题目描述] 摩尔瓦 ...
- 2015 Multi-University Training Contest 6 hdu 5361 In Touch
In Touch Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- codevs 1803 志愿者招募
1803 志愿者招募 2008年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 申奥成功后,布布经过不懈努 ...
- spring boot学习(转)
玩转Spring Boot 前言 首先在这里对Spring Boot做个简单的介绍,对Spring Boot也关注了挺久了,Spring Boot是由Pivotal团队提供的全新框架, ...
- ASP.NET-Session与复杂数据类型
原文链接:http://www.cnblogs.com/fish-li/archive/2013/05/28/3104750.html Session与复杂数据类型 Session有三种工作模式,拿A ...
- HDU 4312 Contest 2
题目要求两点间的最大值作为距离即: 即是切比雪夫距离.而切比雪夫距离与曼哈顿距离的转换却很巧妙. 把平面坐标所有点绕原点逆向旋转45度后,所得点的曼哈顿距离之和除以√2,即是切雪比夫距离.旋转点的公式 ...
- [Gatsby] Install Gatsby and Scaffold a Blog
In this lesson, you’ll install Gatsby and the plugins that give the default starter the ability to t ...