zoukankan      html  css  js  c++  java
  • 知识杂记

    1.栈: 在函数调用时,在大多数的C编译器中,参数是由右往左入栈,然后是函数中的局部变量。注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向函数的返回地址,也就是主函数中的下一条指令的地址,程序由该点继续运行。

    char s1[] = "123456";
    char *s2 = "789654;
    123456是在运行时刻赋值的,而789654是在编译时就确定的。但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
     
    2.const
    const int*p <==>等价于const int (*p)<==>等价于int const (*p)。意思是p指向的数据是常量,不可以被更改。但是指针p本身是可以被更改的。
    int* const p。意思是p是指针常量,不可以被更改。但是p指向的数据可以被更改。
    const int* const p。显然p本身是常量,p指向的变量也是常量。
     
     
    3.指针数组和数组指针
    指针数组:array of pointers,本质是数组,用于存储指针,也就是说数组元素都是指针。在内存中占有多个指针的存储空间。
    int* p[8];
    int a = 4;
    p[0] = &a;
    int b = *p[0];或者*(p[0]),[]优先级比*高。
     
    数组指针:a pointer to an array,本质是指针,即指向数组的指针。在内存中占有一个指针的存储空间。
    int (*p)[4];//指针p指向一个整形的一维数组,数组的长度是4,
    int a[100] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
    p = &a;
    int b = (*p)[0];(b = 1)
    p++;
    b = (*P)[0];(b = 5)
    或者:
    int a[3][4];
    p = a;//二维数组的首地址赋给p,也就是a[0]或者&a[0][0]
    ++p;
    p = a;//p加1后,p的步长是4,所以p现在指向了a[1][]
     
     
    4.如果a是一个数组,即int a[4],那么a和&a
    虽然a和&a值相同,但是意义不同。a是数组名,同时a是数组首元素的地址,也就是&a[0]的值。
    &a是整个数组的地址。
     
    5.sizeof和strlen
    sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小),参数可以是数组、指针、类型、对象、函数等。它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
    strlen(...)是函数,要在运行时才能计算。参数必须是字符型指针(char*。它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。
    char a[10] = "123456";  //sizeof(a) = 10, strlen(a) = 6
    char *p = "123456";     //sizeof(p) = 4,  strlen(p) = 6, sizeof(*p) = 1
    a[0] = 0;               //sizeof(a) = 10, strlen(a) = 0
     6.地址对齐
    当然标准并没有硬性规定怎么对齐,不同架构不同编译器可能对齐策略也不一样。除非指明编译器怎么对齐,不然就是未定义行为。1)数据类型自身的对齐值:就是基本数据的长度,如 sizeof(char)、sizeof(int)。
    2)指定对齐值:#pragma pack (value)时的指定对齐值value。
    3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
    4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。
    有效对齐值N(存放起始地址%N=0)是最终用来决定数据存放地址方式的值。
     struct str
    {
      int i;
      char c;
      int j;
      char cc;
    };
    假设stu从地址0x0000开始存放,i有效对齐值为4,0x0000%4=0,所以其被存放在0x0000到0x0003这4个连续的字节空间中。c有效对齐值为1,0x0004%1=0,所以其被放在0x0004处。j的有效对齐值为4,但是0x0005%4!=0,编译器会补充3个空字节,因此j被存放在起始地址为0x0008空间。同理,cc存储在0x000c处。
    当然结构体本身也要对齐,stu的有效对齐值为4。从而0x000d到0x000f也归结构体所战友,即sizeof(str)=16;
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    查看进程在CPU和内存占用的命令
    Android studio 启动模拟器出现 VT-x is disabled in BIOS 以及 /dev/kvm is not found
    awk命令过滤tomcat的访日日志中IP地址
    windows 2008R2系统程序运行提示无法定位程序输入点ucrtbase.terminate
    k8s中yaml文件pod的语法(转)
    etcd和redis的比较和日常使用场景
    从gitlab或者github采用git clone和download zip的区别
    记录一次mysql查询速度慢造成CPU使用率很高情况
    USG防火墙DHCP设置保留IP地址
    让docker容器开机启动
  • 原文地址:https://www.cnblogs.com/vdvvdd/p/5087834.html
Copyright © 2011-2022 走看看