浅谈数组和指针

  

       数组和指针是很让人敬畏的话题,我只是谈下个人理解和总结:

一、数组和指针的内存分配

数组的内存分配,一维数组和多维数组都是线性分配内存。一个一维数组char a[n] = “abcdefgh”的内存分配模型如下图。

的内存分配模型如下图

a = 9980,并且分配一个内存空间来存储a。这正是数组和指针内存分配的区别之处。

 

指针的内存分配,定义char *p = “abcdefgh”。会为p分配一个内存空间,存储字符串的首地址。正是一般指针的概念。内存分配模型如下图。

内存分配如下图

 

这里需要注意的是:

char *pc = “abcdefgh”; // 定义了一个字符串常量,不能通过引用p来改写

*(p + 1) = ‘g’; //运行时提示错误,内存不能被写

char pp[] = “abcdefg”;

*(pp + 1) = ‘g’; // ok

 

并且只有字符串数组可以这样定义,如果是int类型数组就不能编译通过了。

int *pi = {1, 2, 3}; //编译错误

 

如果是多维数组会怎样呢?

char *pc[3] = {“ni”, “hao”, “!”}; //没问题

int *pi[3] = {{1},{1, 2}, {1, 2, 3}}; //编译错误

后者的解决办法是分解为3个一维数组

int *p1 = {1};

int *p2 = {1,2};

int *p3 = {1,2,3};

int *pi[3] = {p1, p2, p3}; // ok

 

字符指针的另一个用处是把局部变量的指针当做返回值

char* func()                               

{

       char* p = “abcdefg”;

       return p;

}

int main()

{

       cout << func() << endl;

       return 0;

}//能正确输出”abcdefg”

如果字符串改成数组定义方式

char* func()

{

       char p[] = “abcdefg”;

       return p;

}

int main()

{

       cout << func() << endl;

       return 0;

}//输出的会是乱码

 

二、数组与指针的全局变量声明

文件1中的全局变量

char p[] = “abcdefgh”;

文件2中的声明方式

extern char *p; //调用时会出错

extern char p[];//ok

前者错误的原因是,编译器会把字符数组的第一个元素理解为地址。不出错才怪!!

 

相对应的情况

文件1中的全局变量

char *p = “abcdefgh”;

文件2中的声明方式

extern char *p; //ok

extern char p[];//调用时会出错

或者错误的原因是,编译器会将p中的内容(地址)理解为了字符。

 

三、二者的蛋疼区别

对于定义

char* p = “abcdef”;

char pp[] = “abcdef”;

sizeof(p);//打印输出结果为4

sieof(pp);//打印输出结果为6

++ p;//ok

printf(“%s\n”, p);//输出bcdef

++pp;//编译错误,同样不能当做赋值运算的左值,是个常量啊

 

四、编译器实现“大同“

定义如下

char* p = “abcdefg”;

char pp[] = “abcdefg”;

cout << &p << endl;

cout << &pp << endl;

两者都会输出数组的首地址,编译器会将其理解为指针。

 

同样发生将函数参数声明为指针或数组的情况。

void func(char* p){//do something}

void func(char p[]){//do something}

两者作用完全一样。

 

还体现在对数组元素的存取操作

p[1];

*(p + 1)

pp[1];

*(pp + 1);

都能完美运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值