鱼C论坛

 找回密码
 立即注册
查看: 3817|回复: 17

[技术交流] 如果你把这弄懂了,C指针应该就不存在什么问题了吧!

[复制链接]
发表于 2012-8-6 13:50:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前段时间学的指针,一开始觉得不难,到了二维指针就有点蒙了,后来逐渐有点明白,明白了二维指针,指针函数,指针数组,指针的指针,但刚才在论坛上面看到了一个帖子,是关于输入字符串加不加地址符&有什么区别,我就自己写了两段代码,看了一下运行结果,想跟大家讨论一下,代码如下:
#include <stdio.h>

main()
{
        char a[10]="abc";
        printf("%s\n",a);
        printf("%s\n",&a);
        printf("%s\n",&a[0]);
        printf("%s\n",a+1);
        printf("%s\n",&a+1);
        printf("%s\n",&a[0]+1);
        printf("%c\n",*a);
        printf("%c\n",*a+1);
}

#include <stdio.h>

main()
{
        char *a="abc";
        printf("%s\n",a);
        printf("%s\n",&a);
        printf("%s\n",&a[0]);
        printf("%s\n",a+1);
        printf("%s\n",&a+1);
        printf("%s\n",&a[0]+1);
        printf("%c\n",*a);
        printf("%c\n",*a+1);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-6 14:21:41 | 显示全部楼层
#include <stdio.h>

void main()
{
        char a[10]="abc";  
        printf("%s\n",a);                                        //abc
        printf("%s\n",&a);                                        //abc
        printf("%s\n",&a[0]);                                //abc
        printf("%s\n",a+1);                 //bc
        printf("%s\n",&a+1);                                //乱码,我觉得&a等于a+10       
        printf("%s\n",&a[0]+1);             //bc       
        printf("%c\n",*a);                                        //a
        printf("%c\n",*a+1);                                //b
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-6 14:47:48 | 显示全部楼层
首先我自己来解释一下吧!
先说数组a[10]:
&a==a的整个首地址,&a+1指针就会偏移10个内存单元,即从数组a偏移到数组b,假设有数组b
a==&a[0] 即数组首地址,与&a不同的是,a+1指针就会偏移一个内存,即从&a[0]偏移到&a[1]
*a==a[0] 这个就需要过多解释吧!你懂的!*a+1就是a[0]+1==a[1]
我当初学二维指针就是从
&a==a的整个地址     +1偏移整个数组地址
a==&a[0]                  +1偏移一行地址
*a==a[0]==&a[0][0] +1偏移一个地址
**a=a[0][0]                +1偏移一个地址    取值
我现在就是不明白为什么char *a="abc";printf("%s\n",&a);会乱码,而数组a[]不会。。。
求解释!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-6 16:34:55 | 显示全部楼层

我以后会很少来这个论坛。。。既然你这么热心叫我来看,我就来看看,也帮你纠正下。。。这个东西从数据类型的角度去理解。。。

对于数组int a[10] ;

数组名 a的类型是  int[10] 的类型, 也就是一个数组类型,你可以却试试 sizeof(a)  看能打印出什么。

但是它经常可以这样赋值  int * p = a;  这里进行了一个隐式类型转换,所以使很多人误解为a是int *类型。

然后  当然printf("%d",a) 打印出的是这个数组的首地址,这不难理解。一个函数 你打印函数名,也是  函数的首地址。

2: &a .  a的类型是 int [10] 类型,  那么 &a 就是 int [10] *  类型,  换个写法,就是 int (*)[10] 类型。

很明显,这是个数组指针, 那么 &a + 1 就不难理解,  一个指针加上一个常量,等于这个指针加上它指向的数据类型的长度乘以这个常量。。。 数组指针指向整个数组,加1等于 加上 整个数组的长度乘以1.等于是跳过了整个数组。

就这个是个关键,其余我不想多做解释,时间有限

评分

参与人数 1荣誉 +4 鱼币 +4 贡献 +4 收起 理由
丿夏夜灬彬刂 + 4 + 4 + 4 很给力!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-6 16:52:40 | 显示全部楼层
受教了:lol
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-7 11:38:56 | 显示全部楼层
万骨空 发表于 2012-8-6 14:21
#include

void main()

恩,&a就是整个数组的首地址,&a+1就是跳过了这个数组了,所以是乱码,但是为什么char* a="abc" &a就会乱码呢?我想这里*a &a就是指针本身的首地址,而a[10] &a是数组本身的首地址,所以数组a[10],显示首地址是存放的值,而指针*a显示的首地址就是乱码。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-7 12:26:18 | 显示全部楼层
Tzdner_C 发表于 2012-8-6 16:34
我以后会很少来这个论坛。。。既然你这么热心叫我来看,我就来看看,也帮你纠正下。。。这个东西从数据类 ...

恩,你说的很对!其实我觉得关于字符串a[10], &a把数组a看成一个整体,+1就偏移sizeof(a),a就把数组a看成10个单元,+1就偏移一个单元,虽然&a和a都能表示整个字符串,但是这个有本质区别。如果char* a;&a之所以乱码就是因为它指向的值在常量区,不是指针a本身,而数组a[10];&a代表它本身,所以可以索引到数组a[10]的值。
这个问题终于弄懂了,同时希望大家都能弄懂。
还有,你说你以后很少来这里是想到更深入的深造吧?我觉得鱼c真不错,虽然只是入门,相信以后会出更多深入的教程的,当然你也不错,第一次提问就是你解答的,希望你以后成为计算机高手,再回过头来出教学视频给小甲鱼老湿看:lol
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-7 12:29:54 | 显示全部楼层
394428311 发表于 2012-8-6 14:47
首先我自己来解释一下吧!
先说数组a[10]:
&a==a的整个首地址,&a+1指针就会偏移10个内存单元,即从数组a ...

我现在就是不明白为什么char *a="abc";printf("%s\n",&a);会乱码,而数组a[]不会。。。
求解释!!!
首先a是个变量,然后他的数据才是个指针,它也有它的地址即&a,
“abc”是在内存中数据段存储,a  = "abc",就是使a指向该字符首地址,则
printf(“%s\n”,a );能打印出abc,但是&a是数据a的地址 并不是“abc”首地址
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-7 12:44:23 | 显示全部楼层
mddct 发表于 2012-8-7 12:29
我现在就是不明白为什么char *a="abc";printf("%s\n",&a);会乱码,而数组a[]不会。。。
求解释!!!
...

恩,前面的都好理解,就是数组a[10]跟指针*a,为什么都是&a,指针会乱码呢?
因为数组&a是数组本身的地址,而指针&a是指针本身的地址,而“abc”存放在常量区,它们并不相干,只有a可以指向整个“abc”,*a就指向第一个“a”,所以指针&a跟“abc”是没有一毛钱关系的,&a只是指针本身的地址,而数组&a本身的地址正好就是“abc”,我想这个应该不难理解吧!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-7 19:07:50 | 显示全部楼层
394428311 发表于 2012-8-7 12:26
恩,你说的很对!其实我觉得关于字符串a[10], &a把数组a看成一个整体,+1就偏移sizeof(a),a就把数组a看成 ...

我是个搞逆向的,要往安全方面发展。。。所以这个论坛不适合我了。。。

不过,跟你说一句啊,我以前学C语言的时候,老是对这些数组名,指针,数组,这一类的东西纠结,想去弄明白到底怎么回事。。。
直到现在,学的越来越多,写的程序越多的时候,慢慢发现,指针和数组无非就是给我们提供了一种很方便的数据类型。我经常定义一个DWORD  XXX类型的变量,也就是int 类型的变量  存放地址,用的时候
((DWORD *)XXX )[ i ]  这样用,所以在大程序,在真正的运用中,指针 和数组,和普通变量没有界限,个人习惯问题了。。。所以不要在数组和指针之间一些语法书写方式上纠结太多,浪费太多时间。 用的多了你会明白,无非就是为了定义一个变量来存放地址。。。仅此而已。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-8 00:08:34 | 显示全部楼层
Tzdner_C 发表于 2012-8-7 19:07
我是个搞逆向的,要往安全方面发展。。。所以这个论坛不适合我了。。。

不过,跟你说一句啊,我以前学 ...

这是要搞反黑客啊!呵呵,我经过这些天的纠结,现在觉得指针只不过是个工具,算法才是灵魂,设计程序就是要有创新,我还是多研究研究思路问题。
恩,祝你学业有成,然后也不要忘了回头看看鱼C论坛,扶持扶持小甲鱼老湿:lol
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-8 20:40:48 | 显示全部楼层
好温馨的帖子~~~楼主很有耐心啊,回答的鱼油也很耐心啊~~~你邀请的那位也经常回答我疑问,很好的前辈啊~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-10 11:38:34 | 显示全部楼层
指针数组 数组指针 函数指针 函数指针数组 指针做函数参数 全部没提到 这个弄懂了 C指针还是会有问题的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-10 12:46:14 | 显示全部楼层
Believe 发表于 2012-8-8 20:40
好温馨的帖子~~~楼主很有耐心啊,回答的鱼油也很耐心啊~~~你邀请的那位也经常回答我疑问,很好的前辈啊~~

恩,希望大家以后有什么问题的都互相讨论一下,共同进步:lol
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-10 12:50:42 | 显示全部楼层
我是师兄 发表于 2012-8-10 11:38
指针数组 数组指针 函数指针 函数指针数组 指针做函数参数 全部没提到 这个弄懂了 C指针还是会有问题的

我说的这些都是基础啊!比方说数组a[10],在输入的时候为什么可以不加&,为什么a跟&a都可以打印字符串,但是它们在本质上是有区别的,弄懂了这些,特别是多维指针,后面的指针的指针什么的都会完全明白的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-10 13:15:36 | 显示全部楼层
394428311 发表于 2012-8-10 12:50
我说的这些都是基础啊!比方说数组a[10],在输入的时候为什么可以不加&,为什么a跟&a都可以打印字符串,但 ...

可是你说了这么多都只在指针的范围打滚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-8-10 13:17:18 | 显示全部楼层
394428311 发表于 2012-8-10 12:50
我说的这些都是基础啊!比方说数组a[10],在输入的时候为什么可以不加&,为什么a跟&a都可以打印字符串,但 ...

额 没说完就发出去了 晕 这个里加& 和 不加& 都能打印字符串的原因还有一个比较终于的 就算 printf函数是根据 格式字符串 判断参数的类型 所以 你写 %s printf就把参数当成是一个char*
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-8-10 13:31:19 | 显示全部楼层
我是师兄 发表于 2012-8-10 13:17
额 没说完就发出去了 晕 这个里加& 和 不加& 都能打印字符串的原因还有一个比较终于的 就算 printf函数是 ...

我说的是输入,因为编译器只是通过找到首地址打印,直到结束符'\0'出现,所以char a[10]="abc",&a和a打印结果是一样的,但是a+1结果是"bc",因为偏移一个char单位,而&a+1是乱码,因为偏移了整个sizeof(a),即10个char单位。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 16:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表