C语言的指针与数组详解

每次老栽在这一块!
首先来看简单的

char *p = "Jang";//指针表示法创建字符串
char p1[5] = {"Jang"};

现在,就这个例子,分析一下数组首元素的地址和数组的地址
这里写图片描述
很明显,一共可以分为三类地址,一类是“Jang”这个字符常量的地址,一类是指针p的地址,一类是数组的地址。

为什么“Jang"的地址和p的值相同呢?

因为,p的值就是它所指的字符常量”Jang"的地址,而这个“Jang”就是在静态存储区里的“Jang",编译器可以把多次使用的相同字面量存在一处或多处。
为什么p1和&p1的值相同,但是p和&p的值却不同呢?

首先解释p1和&p1的值为什么相同,p1的值是表示的数组首元素的值,&p1的值是数组地址的值,两者相同是因为数组里是保存着”Jang"的副本,而数组地址的值就是从数组首元素开始的
至于p和&p,p的值在静态存储区里的“Jang”的地址,&p是指针p本身的地址,所以p和&p的值自然不同

区别:

1、在以上两种形式中p和p1都表示该字符串的地址,但是p1是常量,即能进行p1+2来表示后2个元素,但是不能++p1,p的类型是指向常量的指针,p本身不是常量,所以既可以p+2,也可以++p;

2、可以修改p1里元素的值,但是不能修改p元素里的值
比如:
p1[2]='m';//可以
p[2]='m';//不可以

3、注意这里&p+1与&p1+1的区别

这里写图片描述
&p1+1表示的是在内存中整个数组后一个元素的地址,所以&p到&p+1的隔了4个char和一个’\0’
&p+1表示的p这个指针后一个地址,指针在32位系统占4个字节,但是我这是64位系统,按理应该是8个字节,产生这个原因主要是因为兼容

4、

char *p = "Jang";   
    printf("%p\n", p);
    printf("%p\n",&p );
    printf("%p\n", &p[0] );
char p1[5] = { "Jang" };
    printf("%p\n", p1);
    printf("%p\n", &p1); 
    printf("%p\n", &p1[0]);

其结果是:

003F6B30
00AFFA54
003F6B30
00AFFA44
00AFFA44
00AFFA44
请按任意键继续. . .

这个比较好理解,就不赘述,在运算过程中,可以认为p是&p[0]的别名,p1是&p1[0]的别名,但是这两者不等同,因为类型不一样

char *p = "Jang";   
    printf("%d\n",sizeof(p));
    printf("%d\n", sizeof(p[0]));
char p1[5] = { "Jang" };
    printf("%d\n", sizeof(p1));
    printf("%d\n", sizeof(p1[0]));
结果:
4//指针类型
1//char类型
5//char[5]类型
1//char类型

相同点:

两者都可以使用p[i]p1[i]的形式

再看复杂点的

char *p2[] = { "ENTER", "NEW", "POINT", "FIRST" };
    printf("%p\n", p2); printf("%p\n", p2+1); 
    printf("%p\n", &p2); printf("%p\n", &p2 + 1); 
    printf("%p\n", &p2[0]); printf("%p\n", &p2[0]+ 1); 
    printf("%d\n", sizeof(p2));
    printf("%d\n", sizeof(p2[0]));
结果:
00FFFB30
00FFFB34
00FFFB30
00FFFB40
00FFFB30
00FFFB34
16
4
请按任意键继续. . .

这个也好理解,p2是一个存了四个指针的数组,指针指向char型字符串
其中&p2与&p2 + 1之间隔了4个指针,即4*4=16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值