数组与指针

数组与指针

一、变量

  • 变量:是一个标识符(identifier),用来指代一块内存区域,使用变量使我们操作内存以区域(area),以块(block)为单位,提高了方便性。变量是内存区域的别名,机器代码中,是不会出现变量名的;变量名是给我们程序员操作内存来使用的,机器码中将变量名替换成了相应的内存地址。

  • 当我们定义int a时,编译器负责为程序预留4字节空间,并把我们的变量名“a”保存进符号表,并用这个符号表的索引对应实际的空间。如果下面出现b = a;那么它就会根据符号表找到变量的真正的物理位置,取得它的值,赋给b。变量名虽然不直接表示地址,但可用取地址符号&来获得它所代表的变量的存放地址。因为在定义变量的同时会分配给它相应的空间。 使用变量来对数据的访问是直接访问。

二、数组

    int array[5] = {12345};

a为数组名,表示数组的首地址,在计算数组中元素的值就是通过这个首地址+数据类型*偏移值而得到的。a=&a[0],因此,a是常量,不能进行a++。

    printf("%d\t",*(array+1));
    int *parray=(int *)(&array+1);
    printf("%d\n",*(parray-1));

在array+1过程中,偏移后的地址为array+sizeof(array)*1;而parray=(int )(&array+1),偏移后的地址为array+sizeof(*&array)*1。
array与&array的值是一样的,都是该数组的首地址,但他们的含义是不一。
array表示该数组的首地址,及首元素的地址;而&array指向整个数组的内存块,每次+1时,array偏移一个类型大小,而&array偏移整个数组的内存块大小,。

三、指针

    int a=5;
    int *p = &a;

指针变量存储的是变量的地址,通过指针变量是对数据的间接访问。

    main.c

    extern char str[];
    int main(void)
    {
        printf("%s\n",str);
        return 0;
    }
test.c

    int *str="guidao\n";

extern char str[]欺骗了编译器,将指针类型的str当成了数组类型来进行解析,输出的是一个错误的字符串,那这个错误的字符串是怎么得到的。由于欺骗了编译器,将str当成了数组,但是str是一个指针,保存了”guidao\n”这个字符串在常量区的首地址,假如地址为0x01880000,使用printf(“%s\n”,str)时,由于编译器将str当成了数组,直接将地址0x01880000解析输出出来,因此我们看到了错误的值,如果想正确输出,则可以强制转化,改为:

    printf("%s\n",(char *)(*(unsigned int *)str));

数组是直接访问,而指针是间接访问。

int array[5] = {1,2,3,4,5};

array[3]读取数值时,通过array + 3*sizeof(*array)来得到地址,从而得到值,而使用:int *parray = array +3;可以直接得到偏移量,使用指针速度会更快。

int array[5] = {1,2,3,4,5};
int *parray = array +3;

array[3]=10;
*paray = 10;

汇编代码

array[3] = 10;
00DB1411  mov         eax,4  
00DB1416  imul        ecx,eax,3  
00DB1419  mov         dword ptr array[ecx],0Ah  

    *parray = 10;
00DB1421  mov         eax,dword ptr [parray]  
00DB1424  mov         dword ptr [eax],0Ah  

使用指针汇编代码更优化。

char str1[5]={'a','b','c','d','f'};
char *str2="guidao\n";

str1可读不可写,*str1可读可写,相当于char *const str1;
str2可读可写,*str2可读不可写,相当于const char *str2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值