the difference between pointer and array (and variable)

2024-01-21 19:32

本文主要是介绍the difference between pointer and array (and variable),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/********************************test,c***********************
song 
8.13
*************************************************************/
#include<stdio.h>  
int i=6;
int cc[9]={1,2,3,4,5,6,7,8,9};
int * const pa=cc;//注意const的位置:不是const int * pa,
int *  ppa=cc;
int bb[2][3]={{0x50,0x51,0x52},{0x53,0x54,0x55}};int main()  
{i=3;
i=3;
*(cc+1)=6;
*(pa+1)=8;
*(ppa+1)=9;
*(*(bb+1)+1)=0x99;
i=2;
i=2;printf("%x\n",i);
printf("%x\n",*(cc+1));
printf("%x\n",*(pa+1));
printf("%x\n",*(ppa+1));
printf("%x\n",*(*(bb+1)+1));printf("%x\n",cc);
printf("%x\n",pa);
printf("%x\n",ppa);
printf("%x\n",bb);printf("%x\n",&i);
printf("%x\n",&cc);
printf("%x\n",&pa);
printf("%x\n",&ppa);
printf("%x\n",&bb);
}
[root@localhost mmap]# ./test
2
9
9
9
99
8049800
8049800
8049800
8049828
80497e0
8049800
8048634
8049824
8049828
//print sections
[root@localhost mmap]# readelf -S test[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al[15] .rodata           PROGBITS        08048628 000628 000014 00   A  0   0  4[24] .data             PROGBITS        080497c0 0007c0 000080 00  WA  0   0 32
//print symblols
[root@localhost mmap]# readelf -s testNum:    Value  Size Type    Bind   Vis      Ndx Name46: 08048634     4 OBJECT  GLOBAL DEFAULT   15 pa53: 08049800    36 OBJECT  GLOBAL DEFAULT   24 cc57: 080497e0     4 OBJECT  GLOBAL DEFAULT   24 i62: 08049828    24 OBJECT  GLOBAL DEFAULT   24 bb65: 08049824     4 OBJECT  GLOBAL DEFAULT   24 ppa
[root@localhost mmap]# objdump -s testContents of section .rodata:8048628 03000000 01000200 00000000 00980408  ................
/*
the address of pa is starting from 8048634 ,length 4 bytes,it's content 
is "00980408" displaying as little endian
actually it is 08049800---the address of cc
*/
Contents of section .data:80497c0 00000000 00000000 00000000 00000000  ................80497d0 00000000 00000000 00000000 00000000  ................80497e0 06000000 00000000 00000000 00000000  ................80497f0 00000000 00000000 00000000 00000000  ................8049800 01000000 02000000 03000000 04000000  ................8049810 05000000 06000000 07000000 08000000  ................8049820 09000000 00980408 50000000 51000000  ........P...Q...8049830 52000000 53000000 54000000 55000000  R...S...T...U...
/*
the address of cc is starting from 08049800 ,4*9=36 bytes length ,we can see it's 
content is 1 2 3 4 5 6 7 8 9 from data section
the address of bb is starting from 08049828 , 4*2*3=24 bytes length
cotent is 50 51 52 53 54 55
the address of i is starting from 080497e0 , 4 bytes length,cotent is 6
the address of ppa is starting from 08049824 , the length and cotent are the same as pa
located in rodata section
*/

可用下图表示变量,指针,数组的内存分分配


[root@localhost mmap]# objdump -S test
080483c4 <main>:80483c4:	8d 4c 24 04          	lea    0x4(%esp),%ecx80483c8:	83 e4 f0             	and    $0xfffffff0,%esp80483cb:	ff 71 fc             	pushl  -0x4(%ecx)80483ce:	55                   	push   %ebp80483cf:	89 e5                	mov    %esp,%ebp80483d1:	51                   	push   %ecx80483d2:	83 ec 14             	sub    $0x14,%esp80483d5:	c7 05 e0 97 04 08 03 	movl   $0x3,0x80497e0//i=3;80483dc:	00 00 00 80483df:	c7 05 e0 97 04 08 03 	movl   $0x3,0x80497e0//i=3;80483e6:	00 00 00 
/*$表示一个立即数,%表示一个寄存器,( )表示寄存器间接寻址
编译器将i用其地址0x80497e0替换掉
翻译为将立即数3移到内存单元0x80497e0*/80483e9:	b8 04 98 04 08       	mov    $0x8049804,%eax//*(cc+1)=6;80483ee:	c7 00 06 00 00 00    	movl   $0x6,(%eax)
/*
编译器将cc+1用cc+1所表示的地址值替换掉
cc+1-->8049800+4=8049804
编译器将*(cc+1)翻译为将计算出来的地址塞进累加器eax,
利用寄存器间接寻址将立即数6塞进内存单元8049804
*/80483f4:	a1 34 86 04 08       	mov    0x8048634,%eax//*(pa+1)=8;80483f9:	83 c0 04             	add    $0x4,%eax80483fc:	c7 00 08 00 00 00    	movl   $0x8,(%eax)
/*
编译器将pa用pa之地址替换下来
编译器将*(pa+1)翻译为将pa地址8048634塞进eax
执行+1操作,即eax=8048634+4=8048638
将立即数塞进8048638内存单元
*/8048402:	a1 24 98 04 08       	mov    0x8049824,%eax//*(ppa+1)=9;8048407:	83 c0 04             	add    $0x4,%eax804840a:	c7 00 09 00 00 00    	movl   $0x9,(%eax)
/*
同*(pa+1)=8;可以看出,指针常量和指针都被编译器翻译成一样的代码,
数组名cc+1,cc[1]等都是编译器编译时执行的的运算
pa+1是程序运行时执行的运算
所以,数组名只是一个c语言的规定,用于编译器计算数组元素的地址值,
c语言在数组范畴规定了这么多的东西,要求我们按照他说的规范去写,然后他在编译的时候,直接套用
规范计算出实际地址,而不是在程序运行的时候去计算指针常量和指针都是有一个32b的内存单元来装其值得
数组名没有
数组名在内存中更像是普通变量(的集合)
但是在c语言中,大部分场合,要将数组名"假想"作一个指针去用,
这是c语言规范,因为 编译时,是将数组名当做指针对待
比如将cc[1]先在内部译成*(cc+1)
这也就解释了指针也可以写成数组的形式,因为即使你写成了数组的形式(不管实际是数组还是指针)
,编译器还是会将其换成指针
一下来自 thq c程序设计
int *p;
int a[10];
p=&a[0](或p=a);
则
p+i,a+i都是a[i]的地址.a[i]也可写作p[i]
*(p+i),*(a+i)都是p+i或a+i指向的数组元素即a[i]的值
比如p+2,代表a[2]的地址,或说p[2]的地址
*/8048410:	b8 28 98 04 08       	mov    $0x8049828,%eax//*(*(bb+1)+1)=0x99;8048415:	83 c0 10             	add    $0x10,%eax8048418:	c7 00 99 00 00 00    	movl   $0x99,(%eax)
/*
8049828+12+4
*/
804841e:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;8048425:    00 00 00 8048428:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;804842f:    00 00 00 8048432:    a1 e0 97 04 08           mov    0x80497e0,%eax8048437:    89 44 24 04              mov    %eax,0x4(%esp)804843b:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048442:    e8 ad fe ff ff           call   80482f4 <printf@plt>8048447:    b8 04 98 04 08           mov    $0x8049804,%eax804844c:    8b 00                    mov    (%eax),%eax804844e:    89 44 24 04              mov    %eax,0x4(%esp)8048452:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048459:    e8 96 fe ff ff           call   80482f4 <printf@plt>804845e:    a1 34 86 04 08           mov    0x8048634,%eax8048463:    83 c0 04                 add    $0x4,%eax8048466:    8b 00                    mov    (%eax),%eax8048468:    89 44 24 04              mov    %eax,0x4(%esp)804846c:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048473:    e8 7c fe ff ff           call   80482f4 <printf@plt>8048478:    a1 24 98 04 08           mov    0x8049824,%eax804847d:    83 c0 04                 add    $0x4,%eax8048480:    8b 00                    mov    (%eax),%eax8048482:    89 44 24 04              mov    %eax,0x4(%esp)8048486:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)804848d:    e8 62 fe ff ff           call   80482f4 <printf@plt>8048492:    b8 28 98 04 08           mov    $0x8049828,%eax8048497:    83 c0 10                 add    $0x10,%eax804849a:    8b 00                    mov    (%eax),%eax804849c:    89 44 24 04              mov    %eax,0x4(%esp)80484a0:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)80484a7:    e8 48 fe ff ff           call   80482f4 <printf@plt>80484ac:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)80484b3:    08 80484b4:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)80484bb:    e8 34 fe ff ff           call   80482f4 <printf@plt>80484c0:    a1 34 86 04 08           mov    0x8048634,%eax80484c5:    89 44 24 04              mov    %eax,0x4(%esp)80484c9:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)80484d0:    e8 1f fe ff ff           call   80482f4 <printf@plt>80484d5:    a1 24 98 04 08           mov    0x8049824,%eax80484da:    89 44 24 04              mov    %eax,0x4(%esp)80484de:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)80484e5:    e8 0a fe ff ff           call   80482f4 <printf@plt>80484ea:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)80484f1:    08 80484f2:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)80484f9:    e8 f6 fd ff ff           call   80482f4 <printf@plt>80484fe:    c7 44 24 04 e0 97 04     movl   $0x80497e0,0x4(%esp)8048505:    08 8048506:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)804850d:    e8 e2 fd ff ff           call   80482f4 <printf@plt>8048512:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)8048519:    08 804851a:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048521:    e8 ce fd ff ff           call   80482f4 <printf@plt>8048526:    c7 44 24 04 34 86 04     movl   $0x8048634,0x4(%esp)804852d:    08 804852e:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048535:    e8 ba fd ff ff           call   80482f4 <printf@plt>804853a:    c7 44 24 04 24 98 04     movl   $0x8049824,0x4(%esp)8048541:    08 8048542:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)8048549:    e8 a6 fd ff ff           call   80482f4 <printf@plt>804854e:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)8048555:    08 8048556:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)804855d:    e8 92 fd ff ff           call   80482f4 <printf@plt>8048562:    83 c4 14                 add    $0x14,%esp8048565:    59                       pop    %ecx8048566:    5d                       pop    %ebp8048567:    8d 61 fc                 lea    -0x4(%ecx),%esp804856a:    c3                       ret    804856b:    90                       nop    804856c:    90                       nop    804856d:    90                       nop    804856e:    90                       nop    804856f:    90                       nop    



这篇关于the difference between pointer and array (and variable)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/630593

相关文章

【uva】11536-Smallest Sub-Array(区间移动问题)

一个区间移动的问题,1A了,感觉没什么好说的。。 13975926 11536 Smallest Sub-Array Accepted C++ 0.809 2014-08-01 11:00:20 #include<cstdio>#include<cstring>#include<iostream>using namespace std;#define INF 1 << 30

leetCode#448. Find All Numbers Disappeared in an Array

Description Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this

安卓错误经验分析之 R cannot be resolved to a variable

当出现 R cannot be resolved to a variable  错误的时候,不能采用编译器建议的修改方法,试着clean一下,然后查找gen文件夹下R.java是否丢失,如果不存在R.java,程序没有报错且采用其它方法均无效,八成是res文件夹下的layout或者manifest出现错误没有显示出来,需要自己查一遍,否则无法根本解决问题,盲目修改代码是没用的。

做一个问卷考试,标准答案对比用户填写的答案,array_diff 进行差集比对

if( empty(array_diff($answer_mark, $answer)) && empty(array_diff( $answer,$answer_mark))){//用户答题正确}else{// 答题错误} 做一个问卷考试,标准答案对比用户填写的答案,array_diff  进行差集比对   如用户填写的答案变量为answer   标准答案为answer_mark

Versioned Staged Flow-Sensitive Pointer Analysis

VSFS 1.Introduction2.Approach2.1.相关概念2.2.VSFS 3.Evaluation参考文献 1.Introduction 上一篇blog我介绍了目前flow-sensitive pointer analysis常用的SFS算法。相比IFDS-based方法,SFS显著通过稀疏分析提升了效率,但是其内部依旧有许多冗余计算,留下了很大优化空间。 以

[LeetCode] 238. Product of Array Except Self

题:https://leetcode.com/problems/product-of-array-except-self/description/ 题目 Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all

[LeetCode] 215. Kth Largest Element in an Array

题:https://leetcode.com/problems/kth-largest-element-in-an-array/description/ 题目 Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not th

pointer-events: auto; 是一个 CSS 属性,

pointer-events: auto; 是一个 CSS 属性,用于控制一个元素是否可以成为鼠标事件(如点击、悬停、拖动等)的目标。以下是对 pointer-events 属性及其值的详细解释: pointer-events 属性 定义: pointer-events 属性控制如何处理鼠标事件。它可以用于控制元素是否响应鼠标事件以及如何处理事件。 pointer-events: auto;

MyBatis - 使用foreach迭代List/Array的说明

在 MyBatis 中的 foreach 元素,主要用于迭代 集合数据 以动态生成执行语句;主要有 item、index、collection、open、separator、close 等属性 属性说明         collection:要迭代的数据集对象,必填项         item:迭代出的元素的别名,必填项         index:元素的序号(map时为k

C++ 原子变量atomic variable

原子变量 原子变量(atomic variable)是 C++11 引入的一种同步机制,用于在多线程环境中进行无锁的、线程安全的操作。原子变量的操作是不可分割的,即在执行过程中不会被其他线程中断,从而避免了数据竞争和不一致的问题。原子变量位于 头文件中。 基本概念 原子性 原子性:一个操作是原子的,意味着它在执行过程中不会被其他线程中断。原子操作要么完全执行,要么完全不执行,不存在部分执行