整形提升
整形提升的规则
1.若是有符号数,则前面8*3位补符号位。
2.若是无符号数,则前面面8*3位补0。
整形提升的意义
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
举例
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned char a = 200;//00000000 00000000 00000000 11001000
unsigned char b = 100;//00000000 00000000 00000000 01100100
unsigned char c = 0;
c = a + b; //1 00101100
//00000000 00000000 00000000 00101100 44
printf("%d %d", a + b, c);//00000000 00000000 00000001 00101100 300
system("pause");
return 0;
} //结果:300 44
int main()
{
char c;
unsigned char uc;
unsigned short us;
c = 128; //11111111 11111111 11111111 10000000
uc = 128; //00000000 00000000 00000000 10000000
us = c + uc; //00000000 00000000 00000000 00000000
printf("0x%x\n",us);
us = (unsigned char)c + uc;//00000000 00000000 00000001 00000000
printf("0x%x\n",us);
us = c + (char)uc;11111111 11111111 11111111 00000000
printf("0x%x\n",us);
system("pause");
return 0;
}
//结果:0x0 0x100 0xff00
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(!c));
return 0;
}
//结果1 4 1
//c只要参与表达式运算,就会发生整形提升,表达式+c ,就会发生提升,所以sizeof(+c)是4个字节.
//表达式-c也会发生整形提升,所以sizeof(-c)是4个字节,但是sizeof(c) ,就是1个字节
数组与指针
int main()
{
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); //16 整个数组的大小
printf("%d\n",sizeof(a+0)); //4 首元素地址的大小
printf("%d\n",sizeof(*a)); //4
printf("%d\n",sizeof(a+1)); //4
printf("%d\n",sizeof(a[1])); //4
printf("%d\n",sizeof(&a)); //4
printf("%d\n",sizeof(*&a)); //16
printf("%d\n",sizeof(&a+1)); //4
printf("%d\n",sizeof(&a[0])); //4
printf("%d\n",sizeof(&a[0]+1)); //4
}
int main()
{
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr)); //6
printf("%d\n", sizeof(arr+0)); //4
printf("%d\n", sizeof(*arr)); //1
printf("%d\n", sizeof(arr[1])); //1
printf("%d\n", sizeof(&arr)); //4
printf("%d\n", sizeof(&arr+1)); //4
printf("%d\n", sizeof(&arr[0]+1)); //4
printf("%d\n", strlen(arr)); //无法确定
printf("%d\n", strlen(arr+0)); //无法确定
//printf("%d\n", strlen(*arr));
//printf("%d\n", strlen(arr[1]));
//printf("%d\n", strlen(&arr));
//printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));//无法确定
}
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //7
printf("%d\n", sizeof(arr+0)); //4
printf("%d\n", sizeof(*arr)); //1
printf("%d\n", sizeof(arr[1])); //1
printf("%d\n", sizeof(&arr)); //4
printf("%d\n", sizeof(&arr+1)); //4
printf("%d\n", sizeof(&arr[0]+1)); //4
printf("%d\n", strlen(arr)); //6
printf("%d\n", strlen(arr+0)); //6
//printf("%d\n", strlen(*arr));
//printf("%d\n", strlen(&arr));
//printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1)); //5
}
int main()
{
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4
printf("%d\n", sizeof(p+1)); //4
printf("%d\n", sizeof(*p)); //1
printf("%d\n", sizeof(p[0])); //1
printf("%d\n", sizeof(&p)); //4
printf("%d\n", sizeof(&p+1)); //4
printf("%d\n", sizeof(&p[0]+1)); //4
printf("%d\n", strlen(p)); //6
printf("%d\n", strlen(p+1)); //5
//printf("%d\n", strlen(*p));
printf("%d\n", strlen(&p));
//printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));//5
}
int main()
{
int a[3][4] = {0};
printf("%d\n",sizeof(a)); //48
printf("%d\n",sizeof(a[0][0])); //4
printf("%d\n",sizeof(a[0])); //16
printf("%d\n",sizeof(a[0]+1)); //4
printf("%d\n",sizeof(*(a[0]+1))); //4
printf("%d\n",sizeof(a+1)); //4
printf("%d\n",sizeof(*(a+1))); //16
printf("%d\n",sizeof(&a[0]+1)); //4
printf("%d\n",sizeof(*(&a[0]+1))); //16
printf("%d\n",sizeof(*a)); //16
printf("%d\n",sizeof(a[3]));//16
}
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
地址加1
大小端
概念:
大端:低地址存放高数据
小端:低地址存放地数据
大小端产生的原因
小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。
如何判断大小端
0x12345678
低地址-----------》高地址
小端模式:78 56 34 12
大端地址:12 34 56 78
将int型的数0x12345678,强转成char(保留低一个字节位)如果是0x78则是小端,如果是0x12则是大端
int check_sys()
{
int i = 0x12345678;
return (*(char *)&i);
}
int main()
{
int ret = check_sys();
if(ret == 0x78)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
}
int check_sys()
{
union u
{
int i;
char c;
}un;
un.i=0x12345678;
return un.c;
}