zoukankan      html  css  js  c++  java
  • 3-C经典题库

    (1)将i定义为无符号的整形:

    ①当i=0时,打印出来是0;

    ②再次执行i--,此时i=-1,在内存中存储为补码形式:0xFFFFFFFF

    ③i是无符号类型,所以最高位不是符号位,满足循环条件,所以将继续循环执行代码

    ④最终循环将一直执行,永远不会出来

    1 unsigned i ;
    2 for (i=9;i>=0;i--)
    3 {
    4 printf("%u
    ",i);
    5 }

    代码运行结果:处于死循环之中

    指针

    (1)

    int main(void)
    {
        int a[4] = {1, 2, 3, 4};
        int *ptr1=(int *)(&a+1);
        int *ptr2=(int *)((int)a+1);
        printf(“%x, %x/n”, ptr1[-1], *ptr2);
        return 0;
    }
    问,在x86平台下输出啥?

    1、&a+1

    首先明确,a是一个具有4个整型变量的数组的名字,具体地说是这种数组的首元素的首地址,而&a是数组的首地址,请注意措辞。而关于指针加1,则需要指针运算的知识。没学过指针运算或者已经忘记了这个知识点的朋友们,下面就是关于指针运算你需要知道的事实:

    就像上面的例子那样,式子&a+1表示的是指针加法运算,而不是普通的数值加法运算,之所以会这样是因为&a是一个指针而非普通数值(虽然它本质上也是一个整数)。那么你会问:假如此时&a=0xFFFF5700,那么&a+1是多少呢?答案是:取决于&a的类型 。

    a) 如果&a是一个指向char型的指针,那么&a+1 = 0xFFFF5701 b) 如果&a是一个指向short型的指针,那么&a+1 = 0xFFFF5702 c) 如果&a是一个指向int型的指针,那么&a+1 = 0xFFFF5704 (32位机器) d) 如果&a是一个指向某种结构体struct foo的指针,那么&a+1 = 0xFFFF5700+sizeof(struct foo) ……

    指针加1不是指针内容简单地加1,而是让指针指向下一个数据 ,加2就是让指针指向下两个数据,这个数据的类型就是指针指向的类型,所以指针的加法究竟会让这个指针指向哪里,取决于这个指针指向的数据类型。

    因此,综上所述,当&a与整数1做加法时,实际上是指针的加法,加1的含义是:令指针a指向下一个数据 ,下一个数据是啥?当然是紧挨着的下一个具有4个整型变量的数组了(因为&a的类型是指向具有4个整型变量的数组的指针嘛),于是a的指向了4的下一个地址,在用此值初始化ptr1,因此ptr1的指向如图所示:

    由于在ptr1初始化的时候,令&a+1强制转换成整型指针,因此ptr1[-1]相当于把ptr1往前挪一个整型大小,即4个字节。 如下图:

    显然,打印出的第一个数字是a[3]的内容,即数值4. 当然,我们还必须说明一个事实:数组下标是可以为负数的,实际上,取下标符“[ ]”的内部实现,就是指针运算!比如a[2],等价于(a+2),即以a地址为基址,取偏移量为2的地址的值。所以ptr1[-1]等价于(ptr-1)。

    2、(int *)((int)a+1)

    至于指针ptr2的处理更恶心一点。它先是把数组名a强制转换成整型变量,然后再加1,此时ptr2指向如下图所示:

    显然,此时打印的内容就是ptr2所指向的往后4个字节的内容了,也就是a{0}的后三个字节和a[1]的第一个字节

    要把上图中每一个字节的内容都打印出来没问题,但要知道字节序的概念,字节序分两种,一种叫大端 字节序(big-endian) ,当然除此之外必然有小端字节序(little-endian) ,让我们用一个问题,来引出字节序的概念,然后再来搞定这两个小鬼吧!

    问题是这样的:对多字节存储的变量,机器是如何做出解释的??请看下图:

    假如这是一个普通的int变量,在32机器上int占用4个字节存储数据,就像上图中显示的那样,在4个字节中放置了一堆数字,但是机器究竟会把这个数解释成0x0103070E(大端模式)呢,还是解释成0x0E070301(小端模式)呢?答案是:都有可能!

    官方解释: 1、所谓大端(big-endian)序,就是高优先位 对应高有效位 。 2、所谓小端(little-endian)序,就是高优先位 对应低有效位 。

    民间解释: 1、所谓大端(big-endian)序,就是读取或者存放数据时,最低 位 对应 高地址 。 2、所谓小端(big-endian)序,就是读取或者存放数据时,最低 位 对应 低地址 。

    回到原来的问题,此时ptr2指向了a[0]的第二个字节。我们以x86平台为例(小端序),此时其内部数据分布是这样的:

    由于x86平台是小端序的,根据咱刚刚讨论过的理论,小端序的存取时最低位对应低地址 ,因此将会打印出0200 0000,如果题目中没有说明在x86平台,那答案是不确定的,取决于具体的平台,例如ARM平台就是大端序的。

    大端模式:00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 0x10000
    小端模式:01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 0x2000000
    内存: -------------------------------->>

     参考:

    https://mengchao.xyz/index.php/archives/328/

    https://cloud.tencent.com/developer/article/1638005

  • 相关阅读:
    Expedition---POJ
    LIS的优化算法O(n log n)
    Super Jumping! Jumping! Jumping! ---HDU
    数据库连接判断
    android stuido控件
    sql查询语句
    c# 字符串操作
    windows操作
    C# sql操作
    datagridview
  • 原文地址:https://www.cnblogs.com/darren-pty/p/13284243.html
Copyright © 2011-2022 走看看