zoukankan      html  css  js  c++  java
  • 幻境奇缘

    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char p[] = "1234567890";
    	char *ppp = p;
    	for(int i = 0; i < strlen(ppp); i++)
    	{
    		printf("%d", i);
    		ppp++;  
    	}
    }
    

    输出结果:01234


    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char p[] = "1234567890";
    	char *ppp = p;
    	for(int i = 0; i < strlen(ppp); i++)
    	{
    		printf("%d %c\n", i,ppp[i]);
    		ppp++;  
    	}
    }
    



    i ppp[i]
    0 1
    1 3
    2 5
    3 7
    4 9






    int a[5]={1,2,3,4,5};
     int *p1=(int*)(&a+1);
     int *p2=(int*)((int)a+1);
     int *p3=(int*)(&a)+1;
        // p3=p3+1;
     printf("%x,%x,%x",p1[-1],*p2,p3[-1]);

    输出结果:5,2000000,1

    首先说一下关于对数组名取地址:
            关于对数组名取地址的问题,由于数组名是右值,本来&array 是不合法的,早期不少编译器就是指定&array 是非法的,但后来C89/C99认为数组符合对象的语义,对一个对象取地址是合理的,因此,从维护对象的完整性出发,也允许&array 。只不过,&array 的意义并非对一个数组名取地址,而是对一个数组对象取地址,也正因为如此,array 才跟&array 所代表的地址值一样,同时sizeof(array )应该跟sizeof(&array )一样,因为sizeof(&array )代表取一个数组对象的长度。

             要注意到 array 和 &array 的类型是不同的。array为一个指针,而&array是指向数组int [100]的指针。array 相当于 &array[0],而 &array 是一个指向 int[100] 的指针,类型是 int(*)[100]。


    另外从步长的角度分析这个问题
    执行如下语句:
    printf("array=%p, array+1=%p/n", array, array+1); 
    printf("&array=%p, &array+1=%p/n", &array, &array+1);

    结果为:
    array=0012FDF0, array+1=0012FDF4     //+sizeof(int)
    &array=0012FDF0, &array+1=0012FF80  //+sizeof(&array)

    在《C专家编程》书中关于数组一章P203,有如下解释:
        无论指针还是数组,在连续的内存地址上移动时,编译器都必须计算每次前进的步长。
        编译器自动把下标值调整到数组元素大小,对起始地址进行加法操作之前,编译器都会负责计算每次增加的步长,这就是为什么指针类型总是有类型限制,每个指针只能指向一种类型的原因所在,因为编译器需要知道对指针进行解除引用操作时应该取几个字节,以及每个小标的步长应取几个字节。
        另外步长的自动调整还和上下语句相关:
     int *p3=(int*)(&a);
          p3=p3+1;
        首先对P3指针变量赋初值,指向数组int [5]的指针,然后对指针进行加一的操作,其中P3定义为一个指向int类型的指针,因此最终P3的值等价P3+sizeof(int)
     int *p3=(int*)(&array+1);
        &array+1,步长为1,其中步长的长度和&array的类型匹配,即&array是指向数组int [100]的指针,所以&array+1等价为&array+sizeof(&array)
     
      最终p1[-1]等价为*(P1-1),因此等价为第二个int [5]的数据首地址(并不存在第二个数组显然当前指针已经越界了,另外数组元素在内存中是连续存贮的)减去一个为sizeof(int)的步长,所以指向了第一个数组的最后1个元素。

    #include <stdio.h>
    
    int a[2] = {1,2};
    int main(){
    	printf("a = %p\n", a); // I
    	printf("&a = %p\n", &a); // II
    	printf("a + 1 = %p\n", a + 1);// III
    	printf("&a + 1 = %p\n", &a + 1);// IV
    
    	return 0;
    }



  • 相关阅读:
    Django REST framework
    Docker学习11-sonarqube+jenkins持续集成代码审计(下)
    Docker学习10-sonarqube+jenkins持续集成代码审计(上)
    jmeter-4-linux下环境搭建 jmeter+ant+docker-jenkins,持续集成测试完成
    jmeter-3-linux下环境搭建jmeter+ant
    jmeter-2-ant+jenkins持续集成测试
    jmeter-1-apache ant-集成测试
    python-50-pip加速与pip包虚拟环境管理
    git-基本操作
    创建 PHP Composer 包并使用的操作指南
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5835321.html
Copyright © 2011-2022 走看看