C 查漏补缺(一)

  • const 修饰变量判断方法
    • 将类型去掉
    • 看const修饰谁,谁的值就是不能改变的
const int *p;//去掉 int 为 const *p ,p所指向的空间里的值不变
int * const p;//p 不变,p不能在指向其它地址
const struct devices dev[5];//去掉类型struct devices 变成 const dev[5],dev[5]数组里的值不变
struct devices const * dev[5];//这是一个devices结构体类型的指针数组,const * dev[5],指针数组dev中每个元素指向的空间里的值不变
char * *p1;//p1是指向char类型指针的指针
const char * *p2;//p2是指向const char类型指针的指针
char * const * p3;//p3是指向char类型const指针的指针
const char * const * p4;//p4是指向const char类型的const指针的指针
char ** const p5;//p5是指向char类型指针的const指针
const char ** const p6;//p6是指向const char类型指针的const指针
char * const * const p7;//p7是指向char类型const指针的const指针
const char * const * const p8;//p8是指向const char类型const指针的const指针
  • 函数指针和指针函数
int * (*pfun)(int);//p是一个函数指针,指向一个有int型的参数,并且返回值是一个int型的指针
int * fun(int);//func是一个指针函数,函数的返回值是指针
pfun = fun//把函数的地址赋给函数指针
(*pfun)(a)//int a ,通过函数指针调用这个函数
不要返回局部变量的指针和引用
  • enum的size
    • C++标准规定,enum的size只要能够容纳定义时刻的所有bits(位)就可以了,具体取什么值,由编译器决定。
    • 比如enum test{ a=2, b=4 };仅需要3bits(00000100),那么可以取1B,也可以取4B,由编译器自己决定。VC中是固定取4B空间。
enum Color
{
    GREEN,      //0
    RED,        //1
    BLUE = 10,  //10
    GREEN_RED   //11
}ColorVal;
  • 枚举与#define宏的区别
    • #define宏常量是在预编译阶段进行简单替换,枚举常量则是在编译的时候确定其值。
    • 一般在编译器里,可以调试枚举常量,但不能调试宏常量。
    • 枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个。
  • 联合体
    • 结构体:各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和。
    • 联合体:各个成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度(遵循对齐),同一时间只能存储1个被选择的变量,对其他成员变量赋值会覆盖原变量
约定为32位系统,即char 1字节、short 2字节、int 4字节

该问题总结为两条规律:
1,每个结构体成员的起始地址为该成员大小的整数倍,即int型成员的其实地址只能为0482,结构体的大小为其中最大成员大小的整数倍
struct A{  
    char a;  
    int b;  
    short c;  
};  
struct B{  
    char a;  
    short b;  
    int c;  
};
sizeof(A) == 12
sizeof(B) == 8
typedef union u
{  
    char a;
    int b[5];
    double c;
    int d[3];     
}U;  
typedef struct s    
{     
    int  e;    
    double f;       
    short g;            
    U h;          
    char i[2]; 
}S;   
U大小至少要容纳最大的b[5]=4*5=20字节,同时要是变量类型最大值得整数倍,即sizeof(double)=8的整数倍,所有sizeof(U)=24

s的大小计算,联合体的自身对齐值为成员变量的最大对齐值,也就double的自身对齐值8(起始地址为0/8),所以s得大小为0+4+4+8+2+6+24+2+6=56
  • 大端小端
    • 大端:低地址—>高地址 数据的高位—>低位
    • 小端:低地址—>高地址 数据的低位—>高位
      • 都是从低地址—>高地址,大端从高位开始
判断大端小端的函数
true/false
bool checkCPU()
{
    union w
    {
        int a;//四个字节
        char b;//一个字节
    }c;
    c.a = 1;
    return (1 == c.b);//小端模式为true
}
a 和 b 共享内存,当是小端模式时低地址是数据低位 1,c.b的值才能是1
  • 按位异或运算
    • 位运算都是补码参与运算
      • 正数的原反补码都相等
      • 负数的补码 = 原码取反(第一位符号位不变)+ 1
    • 不引入第三变量,交换两个变量的值(设a=a1,b=b1)
#include <iostream>
using namespace std;

int main()
{
    int a = 9999, b = 1000;
    a = a^b;
    b = a^b;
    a = a^b;
    cout << a << b << endl;
    return 0;
}
输出 a = 1000, b = 9999;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值