C语言下的指针与数组名的区别及使用

例1
1 #include <stdio.h>
2 #include <string.h>
3 void main()
4 {
5 char *s1=“hello,world”; //此字符串为字符常量,因此编译后不可更改
6 //char str[]=“hello,world”;
7 //char *s1;
8 //s1=str;
9 char s2[]=“hello,world”;//此字符串是数组的初始值,可更改
10
11 printf("%c\n",*s1);//s1为字符指针
12 printf("%c\n",*(s1+1));
13 printf("%c\n",*(s2+1));//s2不是指针,但数组名代表数组首地址,可以运算
14 printf("%s\n",&s1[7]);
15 printf("%s\n",&s2[7]);//9和10行,11和12行结果一样
16 printf("%p\n",s2); //以指针格式输出,无报错,数组名实质是一个常量指针
17 printf(“s2+1:%p\n”,s2+1);
18 printf("%p\n",&s2); //对数组,数组名引用等效数组名取址
19 printf(“str-enddress:%p\n”,s2+strlen(s2)); //本数组尾的地址
20 printf("&s+1:%p\n",&s2+1);
21 printf("%p\n",&s2[0]); //%p输出格式为指针,&和*都只是运算符而已
22
23 }

结果:
h
e
e
orld
orld
0x7fffd35e0c60
s2+1:0x7fffd35e0c61
0x7fffd35e0c60
str-enddress:0x7fffd35e0c6b
&s+1:0x7fffd35e0c6c
0x7fffd35e0c60

解释:
1、数组名代表该数组的首地址,也就是第一个元素(即下标为0)的地址,输出的结果是一样的,见例子的16和21行;
2、C语言下,字符串其实是字符数组,且数组名为常量指针,此常量为数组首地址,上例中如有s2=s1是错误的,会报类型不匹配,因为s2为常量,不能操作,但是s1=s2却是对的;
3、上例第5行,可理解为6、7、8行,区别在于字符串一个是常量,一个是初值,第5行,其在内存中的分布是,“hello,world”字符串在initialized data常量区,s1指针变量在栈中,字符串的首地址在s1中;
4、上例中12行到15行都是通过对元素的引用,12和13是通过地址实现(地址的增减),14和15是通过下标,即通过变量实现;
5、上例的14和15行,通过地址引用,输出为字符串格式(%s),是输出字符串中由此地址开始及后面的所有字符;
6、单独的数组名加不加取址符,结果都是数组的首地址,但在运算时却不一样,如上例的17行,数组名加1,指数组第二元素,即数组名的运算是本数组内的移动,但20行,数组名取址再加1,指的是第二个数组的首地址,即数组名取址后的运算是数组间的移动;
7、对数组中涉及下标操作时,编译器都是将其转换为数组名(常量指针)加偏移实现的(即转为指针运算实现):
a[3]; // 下标形式,自动转换成下面的表达式
*(a + 3);//指针运算形式
8、从上述情况看,指针可用作数组使用(如14行,指针带下标作数组用),但数组不一定能用作指针使用,如下:
int a[] = “hello world”;
printf("%c", *a++); //这里不能改变数组的地址,a不是指针,即a本身不能改变,a++等效a=a+1
但是可以这样使用:
int a[] = “hello world”;
printf("%c", *(a+1)); //没有改变数组地址a,可行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值