让你不再害怕指针
时间:2008-05-13 22:41:06
来源:论坛整理 作者: 编辑:chinaitzhe
大哥们帮忙看看,看还有需要补充的不,假如有错误,请拿起......做爱做的事吧
WORD下载地址(有排版):http://download.csdn.net/source/449890
由于内容比较多,发不上来,所以只给出目录:
- C/C code
Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ 让你不再害怕指针 前言:复杂类型说明 1、细说指针 1.指针的类型 2.指针所指向的类型 3.指针的值----或者叫指针所指向的内存区或地址 4指针本身所占据的内存区 2、指针的算术运算 3、运算符&和* 4、指针表达式 5、数组和指针的关系 6、指针和结构类型的关系 7、指针和函数的关系 8、指针类型转换 9、指针的安全问题 10、结束语
网友回复:支持泡菜
网友回复:
哈哈,沙发有分,呵呵
网友回复:支持!
网友回复:我也支持 !!
网友回复:我也支持!
网友回复:下载看看,呵呵,觉得我的指针把握的不错啊,呵呵,看看有没有新发现
网友回复:分终于散完了,感觉好轻松......
网友回复:
好!
支持&接分
网友回复:
up
网友回复:PC好象有一段时间没上了吧
记得去年的时候常看到你
网友回复:加一句:支持下
网友回复:给条建议:
最好能把指针和数组的相同与不同分出来.
很多初学的,都搞不清.
要这方面内容的留言下,以前看的时候整理过
网友回复:
假如不多的话,就发这来吧,我看能不能加进去..
网友回复:
现在要安心学了,在论坛学进度感觉有点慢
网友回复:好人一个
不但分享资料 而且还可以接分
不顶不行 嘿嘿~
网友回复:支持
网友回复:学习一下, 看有没有我不知道的。。。
感谢一下、、、、
网友回复:支持加接分
网友回复:下一个,瞧瞧,但愿能长见识
网友回复:学习下
网友回复:有分领,不错!
网友回复:支持! 下载了,写的很好!Up,UP!
网友回复:jf
网友回复:支持
网友回复:大力支持啊啊
网友回复:我去看看
谢谢
网友回复:确实,抓紧时间学才是正道
指针与数组的内容在这
网友回复:多谢分享
网友回复:果然不错。
网友回复:支持!
下下来慢慢看!
网友回复:我下载咯 回去研究一哈~~~~~~~~
网友回复:看到这个都怕了.....
网友回复:
狂汗ING
网友回复:学习...
网友回复:收藏中~~~
网友回复:看看。。。顺便接分。。。
网友回复:看见指针我不怕不怕啦,不怕不怕啦,不怕不怕不怕啦~
网友回复:下载看看,谢谢楼主
网友回复:顶一顶。
网友回复:
老大都来顶了,感谢,看能不能补充点东西.....
网友回复:再顶一下
网友回复:下一个来看看,学习
网友回复:不顶不行
网友回复:以造砖码字为荣,以光看不灌为耻;
以消息灵通为荣,以闭塞古董为耻;
以独立思考为荣,以鹦鹉学舌为耻;
以制造八卦为荣,以人身攻击为耻;
以评论交流为荣,以无聊广告为耻;
以有名有姓为荣,以马甲无数为耻;
以天天登陆为荣,以蜻蜓点水为耻;
以迅速回贴为荣,以看贴不回为耻。
网友回复:up
网友回复:指针,朦朦胧胧的..
网友回复:再给顶成楼
PS:怎么看到好几个都用过儿专用的娃娃脸做头像,难道是马甲?
网友回复:papa ...
网友回复:一个小错误:
16页:
本节中提到了函数sizeof(),那么我来问一问,sizeof(指针名称)测出的究竟是指针自身类型的大小呢还是指针所指向的类型的大小?
====================
sizeof不是函数,是操作符.
两者的区别是,函数的结果是运行时得出的,而操作符是编译时行为,假如在编译时得不出结果的东西用sizeof是得不出结果的.
网友回复:up 黄瓜,
网友回复:支持
网友回复:找点资料也挺费劲的
感谢LZ啊
呵呵
网友回复:
恩,非常感谢黄瓜........加20-50分,哈哈
网友回复:发现自己的可用分加了100多,加分,哈哈
网友回复:
网友回复:支持LZ
网友回复:
小补充一下C99中有执行时sizeof
EXAMPLE 3 In this example, the size of a variable-length array is computed and returned from a
function:
#include <stddef.h>
size_t fsize3(int n)
{
char b[n 3]; // variable length array
return sizeof b; // execution time sizeof
}
网友回复:复杂指针解析
来源:http://dev.csdn.net/author/fisher_jiang/5cfa12eeff28446086499d8cf2009cdf.html
因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既闻名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:
The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you
encounter parentheses, the direction should be reversed. Once everything in the parentheses has been
parsed, jump out of it. Continue till the whole declaration has been parsed.
这段英文的翻译如下:
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当碰到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。
现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:
int (*func)(int *p);
首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是 int。
int (*func)(int *p, int (*f)(int*));
func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。
int (*func[5])(int *p);
func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注重这里的*不是修饰 func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
int (*(*func)[5])(int *p);
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
int (*(*func)(int *p))[5];
func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
要注重有些复杂指针声明是非法的,例如:
int func(void) [5];
func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为假如答应函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。
int func[5](void);
func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。
作为练习,下面列几个复杂指针声明给读者自己来解析。
int (*(*func)[5][6])[7][8];
int (*(*(*func)(int *))[5])(int *);
int (*(*func[7][8][9])(int*))[5];
实际当中,需要声明一个复杂指针时,假如把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:
int (*(*func)(int *p))[5];
可以这样分解:
typedef int (*PARA)[5];
typedef PARA (*func)(int *);
这样就轻易看得多了。
答案,同时给出用typedef的分解方法:
int (*(*func)[5][6])[7][8];
func是一个指向数组的指针,这类数组的元素是一个具有5X6个int元素的二维数组,而这个二维数组的元素又是一个二维数组。
typedef int (*PARA)[7][8];
typedef PARA (*func)[5][6];
int (*(*(*func)(int *))[5])(int *);
func是一个函数指针,这类函数的返回值是一个指向数组的指针,所指向数组的元素也是函数指针,指向的函数具有int*形参,返回值为int。
typedef int (*PARA1)(int*);
typedef PARA1 (*PARA2)[5];
typedef PARA2 (*func)(int*);
int (*(*func[7][8][9])(int*))[5];
func是一个数组,这个数组的元素是函数指针,这类函数具有int*的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
typedef int (*PARA1)[5];
typedef PARA1 (*PARA2)(int*);
typedef PARA2 func[7][8][9];
网友回复:居然又加了100分,再顶顶!
- C/C code
Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ //补点小东西 看看 a. VIII int abc(); //返回值为int的函数. b. III int abc[3]; //int型数组. c. X int **abc(); //返回值为"int型指针的指针"的函数. d. XI int (*abc)(); //返回值为int型的函数指针. e. IV int (*abc)[6]; //指向int型数组的指针. f. IX int *abc(); //返回值为"int型指针"的函数. g. XVI int **(*abc[6])(); //指向"返回值为int型指针的指针的函数"的指针的数组. h. VII int **abc[6]; //int型指针的指针数组. i. VI int *(*abc)[6]; //指向"int型指针数组"的指针 j. XIX int *(*abc())(); //返回值为"返回值为int型指针的函数指针"的函数. k. XXI int (**(*abc)())(); //返回值为"返回值为int型的函数指针的指针"的函数指针. l. XXIII int (*(*abc)())[6]; //返回值为"指向int型数组的指针"的函数指针. m. XXV int *(*(*abc)()[6])(); //返回值为"指向'返回值为int型指针的函数指针'的数组的指针"的函数指针. /*练练类型转换 printf 函数类型 int printf(const char *, ...); char* gets(char*) int puts(const char *); 类型转换主要一点就是先使指针指向函数。获取函数的入口地址。 然后,把指针进行类型转换,转换成printf的类型。即是一个函数指针。 */ // #include<stdio.h> #include<conio.h> int main() { void *f = (void *)printf; (*(int (*)(const char *, ...))f)("hello world!"); void *p; p = (void *) printf; (*(int (*)(const char *, ...))p)("\ninput string:\n"); char hello[22]; void *pf = (void *)scanf; (*(int (*)(const char *,...))pf)("%s",hello); (*(int(*)(const char*, ...))f)("printf hello_string :%s\n",hello); fflush(stdin); char s[33]; void *fp = (void *)gets; (*(char* (*)(char*))fp)(s); printf("printf s_string:%s\n",s); printf("puts s_string:%s\n",s); void *ptr1 = (void *)puts; (*(int (*)(const char*))ptr1)(s); return 0; }
网友回复:mark
网友回复:只要不是考题,俺应该都接触过
网友回复:呵呵
支持一下
新手学习指针的时候
是有点转不过来
最重要的是上机实现
网友回复:C99中有执行时sizeof ,看来我的知识有点过时了.多谢飞雪.
网友回复:
的确,咱好象都过时了.......(可能是因为可以进行动态数组的定义,所以加入了这个)
VS2008怎么还不支持C99标准,郁闷
网友回复:收藏
网友回复:恩,支持。
大二的时候用C实现了斐波纳契堆,对指针总算有一个较深的理解。
网友回复:支持,真好
网友回复:受教了,谢谢楼主!!
网友回复:为什么要怕。
网友回复:...........................
网友回复:C和指针上的??
网友回复:接点分,,,嘿嘿
网友回复:楼主,真是太好心了~!
排版不错~!
网友回复:好帖,留名.
网友回复:谢谢楼主
网友回复:接分,支持一下!
网友回复:集合几本牛书的一起来看一下指针应该能明白了。我也搞了很长时间在指针方面。
网友回复:我以前以为我的指针学得不错的,现在觉得很惭愧,哎~
网友回复:学习学习...
网友回复:up!
网友回复:指针确实是程序员的噩梦,学习了
网友回复:专为蹭分而来...
网友回复:顶一个
学习学习
网友回复:
网友回复:
网友回复:刚才去下载了,呵呵,不错,辛劳了!~
网友回复:mark
网友回复:怎么打不开呀?
网友回复:分多啊。
网友回复:该回复于2008-05-12 10:02:07被版主删除
网友回复:mark
网友回复:mark!
网友回复:支持 节分
网友回复:谢谢楼主的贡献!
网友回复:
网友回复:想了解更多IT技术,请登陆:http://www.ciitc.com
网友回复:下个看看
网友回复:下载兼接分 ,3KS
网友回复:支持,支持
网友回复:支持楼主!!
顶了!!
学习中!!
网友回复:up
网友回复:
居然敢跑我的帖中接分,你的右臂还要不要........
网友回复:
不会吧........
网友回复:谢谢楼主了,up!
网友回复:jf
网友回复:
网友回复:不知还有没有机会接分啊 ~_~
网友回复:看了目录我不怕不怕了
网友回复:支持
网友回复:下载了 接个分 谢谢分享
网友回复:刚刚看完,楼主总结得很好,让我发现了自己在指针上很多薄弱的地方。再次感谢!
网友回复:
似乎又加分了!~应该有机会,呵呵!
网友回复:
哦???那得仔细看看了,刚下载下来就放到文件夹里了,没来得及看。
网友回复:
网友回复:
你好JHC,KWKW,P FTJBYH Q QTGEBM GO B
网友回复:支持
网友回复:支持不要资源分的!
网友回复:支持!学习中
网友回复:要pdf格式的
网友回复:ding
网友回复:
PDF格式有啥好的,都黑乎乎的,都突出不了重点
网友回复:ms..PC很小,,上高中吗
网友回复:谢谢,虽然我还没有看
网友回复:
谁告诉你的?我看上去有这么小吗,唉,难怪没女朋友,CRYING...........
网友回复:楼主厉害 顶你!
关键字:不再,害怕,指针,
下一篇:下面没有链接了











文章评论
共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面