1 指针和数组的区别
(1)指针和数组的分配
数组是开辟一块连续的内存空间,数组本身的标识符(也就是通常所说的数组名)代表整个数组,可以使用sizeof来获得数组所占据内存空间的大小(注意,不是数组元素的个数,而是数组占据内存空间的大小,这是以字节为单位的)。举例如下:
#include <stdio.h>
int main(void) { char a[] = "hello"; int b[] = {1, 2, 3, 4, 5};
printf("a: %d\n", sizeof(a)); printf("b memory size: %d bytes\n", sizeof(b)); printf("b elements: %d\n", sizeof(b)/sizeof(int));
return 0; }
|
数组a为字符型,后面的字符串实际上占据6个字节空间(注意最后有一个\0标识字符串的结束)。从后面sizeof(b)就可以看出如何获得数组占据的内
存空间,如何获得数组的元素数目。至于int数据类型分配内存空间的多少,则是编译器相关的。gcc默认为int类型分配4个字节的内存空间。
(2)空间的分配
这里又分为两种情况。
第一,如果是全局的和静态的
char *p = “hello”;
这是定义了一个指针,指向rodata section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是编译器优化的一个措施。
char a[] = “hello”;
这是定义了一个数组,分配在可写数据块,不会被放到字符串池。
第二,如果是局部的
char *p = “hello”;
这是定义了一个指针,指向rodata
section里面的“hello”,可以被编译器放到字符串池。在汇编里面的关键字为.ltorg。意思就是在字符串池里的字符串是可以共享的,这也是
编译器优化的一个措施。另外,在函数中可以返回它的地址,也就是说,指针是局部变量,但是它指向的内容是全局的。
char a[] = “hello”;
这是定义了一个数组,分配在堆栈上,初始化由编译器进行。(短的时候直接用指令填充,长的时候就从全局字符串表拷贝),不会被放到字符串池(同样如前,可能会从字符串池中拷贝过来)。注意不应该返回它的地址。
(3)使用方法
如果是全局指针,用于不需要修改内容,但是可能会修改指针的情况。
如果是全局数组,用于不需要修改地址,但是却需要修改内容的情况。
如果既需要修改指针,又需要修改内容,那么就定义一个数组,再定义一个指针指向它就可以了。
2 我编写的修改方案
[armlinux@lqm pointer]$ cat pointer.c /* * Copyright 2007 (c), Shandong University * All rights reserved. * * Filename : test.c * Description: about pointer * Author : Liu Qingmin * Version : 1.0 * Date : 2007-08-27 */
#include <stdio.h>
/* * define a macro which is used to debug array mode and pointer mode. * if 1, debug array mode; else debug pointer mode. * You can change it according to your decision. */ #define ARRAY_OR_POINTER 0
int main(void) { char *p1; char *p2; char **pp;
//test1
#if ARRAY_OR_POINTER char ch[] = "hello, world!\n";
printf("%d, %d, %d, %d\n", sizeof(p1), sizeof(p2), sizeof(pp), sizeof(ch)); #else char *ch = "hello, world!\n";
printf("%d, %d, %d, %d\n", sizeof(p1), sizeof(p2), sizeof(pp), sizeof(ch)); #endif
//test2
p1 = ch;
#if ARRAY_OR_POINTER pp = &p1; #else pp = &ch; #endif
p2 = *pp;
if (p1 == p2) { printf("p1 equals to p2\n"); } else { printf("p1 doesn't equal to p2\n"); }
return 0; }
|
执行结果如下:
// ARRAY_OR_POINTER为0时
[armlinux@lqm pointer]$ ./test 4, 4, 4, 4 p1 equals to p2 // ARRAY_OR_POINTER为1时
[armlinux@lqm pointer]$ ./test 4, 4, 4, 15 p1 equals to p2
|
如果使用了数组定义方式,而又使用pp=&ch,那么就会出现类似下面的错误:
[armlinux@lqm pointer]$ make
gcc -Wall -g -O2 -c -o pointer.o pointer.c
pointer.c: In function `main':
pointer.c:44: warning: assignment from incompatible pointer type
gcc -Wall -g -O2 pointer.o -o test
[armlinux@lqm pointer]$ ./test
4, 4, 4, 15
p1 doesn't equal to p2
阅读(402) | 评论(0) | 转发(0) |