`
txf2004
  • 浏览: 6868199 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

指针赋值 int a[5]={.... ...}, a 、&a[0]、 &a三者之间的区别 浅析 C/C++求职面试必备考点(五)

 
阅读更多

首先,来看代码:

#include <stdio.h>
void main()
{
char a[] = "BruceLee!";
char *p = a;
printf("%c\n", *(p+4));
printf("%c\n", p[4]);
printf("%s\n", p);
printf("%c\n", a[4]);
printf("%c\n", *(a+4));
printf("%s\n", a);
}

首先程序声明了字符数组a,并且初始化,这个记得是默认后面加'\0'的。然后声明了字符指针,指向数组a的首地址,也是a[0]的地址,这里
char *p = a; 等价于char *p = &a[0]
。*(p+4) = p[4] = a[4] = *(a+4),这是最终的结果。这里需要注意的是,字符指针p和数组的名字a每个都有两种引用方法,一种是数组的引用方法如a[4],一种是*(a+4),指针的方法。

注意这里的

printf("%s\n", p);打印的内容仍然是
BruceLee!

也就是说我们仅仅是通过*(p+4),来查看里面的内容,但并没有改变p的指向。p仍然指的是首地址,所以打印出的字符串也是从首字符开始的。

如果我们再代码中,加上这两句:

printf("%c\n", *p++);
printf("%s\n", p);

第一句执行结果是打印首字符‘B’,然后p往后移一位。所以下面一句打印字符串,直接从第二个字符开始的,结果是ruceLee。

总结:(*p+4)这种方式并未改变指针p的指向。只有p++、p--或者p+=4类似这种方式,才改变指针p的指向!

下面再来看一个例子:

#include <stdio.h>
void main()
{
    int a[5] = {1, 2 ,3 , 4, 5};
    int *p = a;
    printf("%d\n", a[0]);
   printf("%d\n", *p);
   printf("%d\n", p);
   int *q = (int *)a;
   printf("%d\n", q[0]);
   
}
需要说的有两点:

1,

printf("%d\n", p);
这句话是不能正常执行的,打印出来和数组a毫无相关的数字。不要期望像printf(“%s”, p)p为首地址。这种方式企图打印整个数组a的内容!

2,int *p = a; 和 int *q = (int *)a,这两句话效果是一样的,在这里加不加前面的强制转换都一样。

再看这个迷惑性强的例子:

#include <stdio.h>
void main()
{
    int a[5] = {1, 2 ,3 , 4, 5};
     int *m = (int *)&a[0];
     printf("%d\n", *(m + 1));
    int *p = (int *)&a;
    printf("%d\n", *(p + 1));
    int *q = (int *)(&a + 1);
    printf("%d\n", *(q-1));
    int *w = (int *)(&a[0] + 1);
     printf("%d\n", *(w-1)); 

   
}
有三个要点:

1,注意上面我们说那么(int *)可有可无,但是当加了&后,在int *m = (int *)&a[0]这里,如果不加强制转换会报警,因为这里取了地址,最好强制转换一下!

2,(int*)(&a[0]) 和(int *)(&a),从打印m和p的值来看,貌似这两种操作是没有区别的,但其实并非如此!&a[0] = a,都是代表数组a的首地址,也就是a[0]的地址。但&a是整个对象,也就是a这个数组整体的首地址。紧跟其后的指针q的申明,&a + 1究竟是谁的地址呢?

我们要切记,对指针进行加1操作,得到是下一个元素的地址,而不是原有地址的数值直接加1,这点大家肯定都知道。假设类型为x,则加1后,指针向后移动sizeof(x),移动是以sizeof(x)为单位的!

我怎么越说越不明白了,其实就是a和&a[0]以及&a,三者的区别!

前两个是等价的。&a上面也说过了,把a看成一个整体,所以&a + 1是a下一个对象的地址,即&a + 1,以相对a或者&a[0]来说,移动了sizeof(a) = 5*4 = 20个字节,即这里指针q指向a[5]!所以*(q - 1)的值是5,也就是a[4] 的值。 为了对照区别,最后我取了(&a[0] + 1)来做对照,w在申明时指向a【1】,*(q-1)的值是1,也就是a[0]的值。

3int *n = a 等价于 int *n = (int *)&a[0] ,从指向上来看也等价于 int *n = (int *)&a;

但 当有指针加减操作时,两者的结果绝不相同!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

如:int *n = (int *)(&a[0] + 1)绝不等于 int *n = (int *)(&a + 1)。




分享到:
评论

相关推荐

    C++复习资料之系列

    (a) 0 (b) 5 (c) 10 (d) 无限 7.以下死循环的程序段是( b )。 (a) for(int x=0;x;){ x++;}; (b) int k=0; do { ++k;} while( k&gt;=0 ); (c) int a=5;while(a){ a--;}; (d) int i=3;...

    数据类型的强制转换实例

    //类型强制转换实例 #include &lt;windows.h&gt; #include &lt;iostream.h&gt; ... //将int类型的指针变量强制转换为lx型指针后赋值给plx111. plx111-&gt;a=4; //正确. cout&lt;&lt;" plx111-&gt;a="&lt;&lt; plx111-&gt;a; } */

    C++对象和指针的引用

    关于给指向函数的指针赋值的格式如下: &lt;指向函数的指针名&gt;=&lt;函数名&gt; 关于在程序中,使用指向函数的指针调用函数的格式如下: (*&lt;指向函数的指针名&gt;)(&lt;实参表&gt;) 如果是指向类的成员函数的指针还应加上相应...

    彻底搞定C 指针 (完全版 ·修订增补版)

    A类:规范化............................................................................................................................3 B类:更正.....................................................

    你必须知道的495个C语言问题(PDF)

    4.4 我有个函数,它应该接受并初始化一个指针void f(int *ip) f static int dummy = 5; ip = &dummy;g 但是当我如下调用时: int *ip; f(ip); 调用者的指针却没有任何变化。. . . . . . . . . . . . . . . 18 4.5 我...

    计算机基础与程序设计.doc

    则正确的指向数组元素的指针赋值是( ) (分数:2分) A. p=*a B. p=a[0] C. p=a D. p=a+1 E. p=*(a[0]+1) 正确答案:AB 3、设有说明:char s[20]; 下面各项中能够正确的将一个字符串"abcd"赋给s数组的有( ...

    智能指针shared-ptr的用法.pdf

    获取原始指针 std::shared_ptr&lt;int&gt; p4(new int(5)); int *pInt = p4.get(); 指定删除器 智能指针可以指定删除器,当智能指针的引⽤计数为0时,⾃动调⽤指定的删除器来释放内存。std::shared_ptr可以指定删除器的...

    11.第十一章 指针.txt

    不能用一个数给指针变量赋值,但是指针可用0赋值,代表空指针,即不指向任何数据。 c.给指针变量赋值时,指针变量前不能加*。 如:int i; int *pi; *pi=&i; /*写法错误,应该为pi=&i*/ pi赋值&i后可用*pi间接...

    第三章JAVA 中的数组及字符串.doc

     也可以在定义时,直接赋值如:int a[]={1,2,3,4,5};(这一点与C相同);   其它与C语言中的数组概念相同,包括利用数组下标赋值、取值以及内存中的存储方式等。  与C语言不同,数组也是类(对象),有许多...

    你必须知道的495个C语言问题

    4.4 我有个函数,它应该接受并初始化一个指针void f(int *ip) f static int dummy = 5; ip = &dummy;g 但是当我如下调用时: int *ip; f(ip); 调用者的指针却没有任何变化。. . . . . . . . . . . . . . . 18 4.5 我...

    20春北交《JAVA语言设计》在线作业一-0006参考答案.doc

    北交《JAVA语言设计》在线作业一-0006 试卷总分:100 得分:100 一、单选题 (共 25 道试题,共 75 分) 1....3,则对x数组元素错误的引用是( ) A.x[k+5] B.x[k] C.x[5-3] D.x[0] 答案:A 18.下列语句序列

    指针数组和数组指针的区别.doc

     char *a[]定义了一个指针数组,注意不是char[], char[]是不能同时初始化为三个字符的,定义以后的a[]其实内部有三个内存位置,分别存储了abc\0,cde\0,fgh\0,三个字符串的起始地址,而这三个位置的内存地址却不是这三个...

    北交《JAVA语言设计》在线作业二.docx

    A.public void main(String arg[]) B.public static void main(String[]args) C.public static void main() D.public static int main(String[]arg) 答案:B 5.下列代码中,将引起一个编译错误的行是( ) 1)public ...

    世界500强面试题.pdf

    1.4.7. 通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小 94 1.4.8. 计算 1 到 N 的十进制数中 1 的出现次数 ............................................. 97 1.4.9. 栈的 push、pop ...

    多台设备修理最优化问题

    int i=0,sum=0,n,max=0,u;//n为顾客个数 float vt,p; ifstream in("input.txt"); if(in.fail()) { cout!"; exit(1);//抛出一个异常窗口 } ofstream out("output.txt"); out.setf(ios::fixed); //对输出设置精度...

    你必须知道的495个C语言问题(完整版本)

    1.11 代码 int f() f char a[] = "Hello, world!";g 不能编译。 . . . . . . . 5 1.12 这样的初始化有什么问题?char *p = malloc(10);编译器提示“非 法初始式”云云。 . . . . . . . . . . . . . . . . . . . . . ...

    From C to C++

    void ask(int a){child::ask(a);} void ask(); }; // --- pupil::pupil(char *n,int a,char *b): child(n,a) { strcpy(book,b); } // --- void pupil::ask() { cout; } //---------- int main(){ child tom,...

    C# for CSDN 乱七八糟的看不懂

    注意,如果定义数组为 int[5] ,则从 0~4。 数组长度 line0.GetLength(1) 数组赋值 可以从一个已经赋值的数组 array2 向未赋值的同等数组 array1 赋值,用 array1=array2; 这时,array1 就变成和 array2 一样的...

Global site tag (gtag.js) - Google Analytics