柔性数组笔记_i++


注意:计算sizeof(结构体)的时候,并不计算柔性数组的占用的空间,但柔性数组存放的数据和结构体其他成员相邻结构体里的柔性数组并不是一个指针,而是 一个标志

柔性数组笔记_柔性数组_02

// 不允许
char str[];

// 允许,因为形参arr最终是一个指针类型
void fun(int arr[]){

}

int main() {
// 不允许
int arr[0];
return 0;
}

柔性数组笔记_i++_03


定长结构体

柔性数组笔记_数据_04


柔性数组笔记_i++_05


柔性数组的使用

struct buffer {
int num;
int size;
char data[];
};

// 结构体大小:sizeof(struct buffer) = sizeof(num) + sizeof(size) = 8B
// 使用的时候,只需要开辟一次空间

int main(){
int n = strlen("hello") + 1;
// 申请空间
struct buffer* p_buffer = (struct buffer*)malloc(sizeof(struct buffer) + sizeof(char) * n);
if (NULL == p_buffer) {
exit(EXIT_FAILURE);
}
p_buffer->num = 1;
p_buffer->size = n;
memcpy(p_buffer->data, "hello", n);
//释放空间
free(p_buffer);
return 0;
}

思考题

struct da_node {
int num;
int data[]; // 内存上并不属于struct da_node,但内存相邻
};

struct dk_node {
int num;
int data[3];
};


int main(){
struct da_node da1 = { 1,2,3,4,5,6,7,8,9 };// 柔性数组任意放数据
struct da_node da2 = { 1,{2,3,4}};
struct dk_node da3 = { 1,2,3,4 };

int len = sizeof(da1); // 4
len = sizeof(da2); // 4
len = sizeof(da3); // 16
len = sizeof(struct da_node); // 4
len = sizeof(struct dk_node); //16
return 0;
}

柔性数组笔记_i++_06

柔性数组笔记_i++_07


柔性数组笔记_柔性数组_08


柔性数组笔记_i++_09

int main() {
char a = 100; // 100
char b = 200; // 72 - 128
char c = a + b; // 100 + 72 - 128 = 44
printf("%d %d\n", c, a + b); // a + b时,都转为int计算,不溢出

unsigned char x = 100;
unsigned char y = 200;
unsigned char z = x + y; // 300 - 255 - 1
printf("%d %d\n", z, x + y);
return 0;
}

柔性数组笔记_柔性数组_10

柔性数组笔记_i++_11

柔性数组笔记_i++_12

柔性数组笔记_i++_13

4294967291表示1111 1111 1111 1111 1111 1111 1111 1011的无符号十进制表示

int main() {
char c = 128; // 1000 0000
printf("%d\n", c); // 127过了就是-128

unsigned char uc = 128; // 1000 0000
unsigned short us = 0; // 0000 0000 0000 0000
// c扩充为int: 1111 1111 1111 1111 1111 1111 1000 0000
// uc扩充为int: 0000 0000 0000 0000 0000 0000 1000 0000
// c + uc : 1 0000 0000 0000 0000 0000 0000 0000 0000
// us :1000 0000
us = c + uc;
printf("%x\n", us);//0

//(unsigned char)c扩充为int:0000 0000 0000 0000 0000 0000 1000 0000
// uc扩充为int:0000 0000 0000 0000 0000 0000 1000 0000
//(unsigned char)c + uc : 0000 0000 0000 0000 0000 0001 0000 0000
us = (unsigned char)c + uc;
printf("%x\n", us);// 0100


//c扩充为int: 1111 1111 1111 1111 1111 1111 1000 0000
//(char)uc扩充为int: 1111 1111 1111 1111 1111 1111 1000 0000
//c + (char)uc : 1 1111 1111 1111 1111 1111 1111 0000 0000
// us: 1111 1111 0000 0000
us = c + (char)uc;
printf("%x\n", us);//ff00


//(unsigned short)c扩充为int: 0000 0000 0000 0000 1111 1111 1000 0000
// uc扩充为int: 0000 0000 0000 0000 0000 0000 1000 0000
//(unsigned short)c + uc: 0000 0000 0000 0001 0000 0000 0000 0000
// us: 0000 0000 0000 0000
us = (unsigned short)c + uc;
printf("%x\n", us);//0
return 0;
}

:对于有符号类型扩充,永远只是扩充符号位,扩充成对应类型的字节大小

int main() {
char a = -1; // 1111 1111
unsigned char b = a; // 1111 1111
// 比较的时候,转int
// a转int:1111 1111 1111 1111 1111 1111 1111 1111
// b转int:0000 0000 0000 0000 0000 0000 1111 1111
if (a == b) {
printf("%d == %d\n", a, b);
}
else {
printf("%d != %d\n", a, b); // -1 != 255
}
}
int main() {
char a = 128; // 1000 0000
unsigned char b = a; // 1000 0000
// 比较的时候,转int
// a转int:1111 1111 1111 1111 1111 1111 1000 0000
// b转int:0000 0000 0000 0000 0000 0000 1000 0000
if (a == b) {
printf("%d == %d\n", a, b);
}
else {
printf("%d != %d\n", a, b); // -128 != 128
}
}

柔性数组笔记_柔性数组_14

查看数据二进制形式中1比特位的数量:

int bits1(unsigned char x){
int cnt = 0;
while(x != 0){
if(x & 1 == 1){
cnt++;
}
x >>= 1;
}
return cnt;
}

int bits2(unsigned char x){
int cnt = 0;
if(x == 0){
return cnt;
}
// 丢弃低位的一个1
while( x &= (x-1) ){
cnt++;
}
return cnt+1;
}

数组中所有数字都出现偶数次,找出出现奇数次的数字

int main() {
int arr[] = { 1,1,2,1,1,2,3,3,6,5,5,6,6 };
int num = 0;// 和0异或不变,和1异或取反
if (arr == nullptr) {
return 0;
}
// 异或:相异为1,相同为0
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
num ^= arr[i];
}
printf("%d\n", num);
}