数组名与指针
首先,指针就是指针,数组就是数组
。两个是不同的东西。这两个概念之所以经常被混淆,是因为编译器把数组名当作指向该数组第一个元素的指针。正是由于数组即数组的本身属性,使用&操作符取的是数组的地址,sizeof()的操作数得到的是整个数组的大小
,而不是所指向第一个元素的大小。
#include <stdio.h>
int main(void)
{
char str[]="abcd";
printf(" (*str) = %c \n",*str);
printf(" addr (str[0]) = %#x \n",&(str[0]));
printf(" addr (str[1]) = %#x \n",&(str[1]));
printf(" addr of arrary param = %#x \n",&str);
printf(" sizeof str = %d \n\n",sizeof(str));
return 0;
}
指针声明和数组声明
首先看一段崩溃代码,Segment Default报错。指针声明和数组声明若没弄清楚,分分钟让你掉坑里
。
#include <iostream>
using namespace std;
int main()
{
char *chas = "ABCDE";
char chas_1[] = "ABCDE";
chas[0] = 'X';
chas_1[0] = 'X';
return 0;
}
上面代码崩溃的原因是:*chas = "ABCDE"存放在常量区
是无法修改的(chas的指针值存放在栈中。而数组是局部变量,存放在栈中
,是可以修改的。
这两种变量的内存布局的不同,导致了指针声明和数组声明有以下区别:”读“ ”写“ 能力
char *a = “abcd”; 此时”abcd”存放在常量区。通过指针只可以访问字符串常量,而不可以改变它。
而char a[20] = “abcd”; 此时 “abcd”存放在栈。可以通过指针去访问和修改数组内容。
赋值时刻
char *a = “abcd”; 是在编译时就确定了
(因为为常量)。
而char a[20] = “abcd”; 在运行时确定
存取效率
char *a = “abcd”; 存于静态存储区。在栈上的数组比指针所指向字符串快
。慢
而char a[20] = “abcd”; 存于栈上。快
再看看下面代码
//合法
char a[]="abcde";
char *b;
b = a;
//不合法
char *a="abcde";
char b[6];
b = a;
char[] 可以隐式转换成 char*
,所以合法。不存在
隐式转换使得 char* 被转换成 char[],char[] 类型的变量不能被赋值,数组不能作左值
,所以不合法。