日期:2023年6月28日`学习内容:C++数据类型&运算符&原反补码
记录我比较模糊的内容,与其他语言相似的不做记录
//提前:变量声明 需要加extern修饰 extern int data;
void test03()
{
//先使用
cout<<"data="<<data<<endl;
}
//后定义
int data = 0;
字符型初始化’\0’
代码如下(示例):
char ch = '\0';
int num = 0;
float f = 0.0f;
double d = 0.0;
字符型初始化’\0’
代码如下(示例):
//有符号数
int num; //默认省去signed
signed int num ;
//无符号数
unsigned int num;
以一个字节为例:
无符号数范围:
0000 0000 ~ 1111 1111
0 ~ 255
有符号数范围:
1111 1111 ~ 1000 0000 ;0000 0000 ~ 0111 1111
-128 ~ -0 0 ~ 127
因为-0 不好表示所以将其看做-128
所以无符号数的范围为:
-128 ~ 0 ~ 127
统一了0的编码
+0补码:0000 0000 -0补码:0000 0000
将减法运算变成加法运算
10: 0000 1010
-6: 1000 0110
-------------------
1001 0000---->-16结果有问题
10: 0000 1010
-6: 1111 1010
-------------------
0000 0100---->4
//const修饰data为只读变量 data的本质是变量 //只读变量 只能被初始化 不能被赋值
const int data=100;
data = 10;//err
如果以常量初始化 const修饰的只读变量 那么 只读变量的值 事先存放在“符号常量表中” 不会立即给data 开辟空间,当对data取地址时,系统才会为data开辟空间
const int data=100;
int *p = (int *)&data;
*p = 2000;
cout<<"*p = "<<*p<<endl;//2000
cout<<"data = "<<data<<endl;//100
register:
register int data=0;//data将放入寄存器中 //尽量不要对寄存器变量取地址
&data;
//register修饰的变量 只是尽量放入寄存器中
volatile int data=0;//对data的访问 必须冲内存访问
//INT32就是int类型的别名 typedef int INT32;
INT32 data;
int num;//已有的类型任然有效
typedef int MYARRAY[5];
MYARRAY arr;
typedef int *MYP;
MYP p;//int *p; p的类型就是int *类型
int data1 = -10;
unsigned int data2 = 6;
if(data1+data2>0)
{
cout<<">0"<<endl;//结果输出 }
else
{
cout<<"<=0"<<endl;
}
如果:data=0000 0001 如果:data=0000 0001 如果:data=0000 0001 如果:data=0000 0001 ...... 如果:data=0000 0001
data=data<<0; data=0000 0001 == 1==data*2^0
data=data<<1; data=0000 0010 == 2==data*2^1
data=data<<2; data=0000 0100 == 4==data*2^2
data=data<<3; data=0000 1000 == 8==data*2^3
data=data<<6; data=0100 0000 == 64==data*2^6
右移操作:
算术右移、逻辑右移 都是编译器决定,用户无法确定。 无符号数:右边丢弃 左边补0
有符号数:
正数:右边丢弃 左边补0 负数:右边丢弃 左边补0(逻辑右移)
负数:右边丢弃 左边补1(算术右移) 编写代码测试 编译器为那种右移:
如果:data=1000 0000 data=data>>0; data=1000 0000 == 128==data除以2^0
如果:data=1000 0000 data=data>>1; data=0100 0000 == 64==data除以2^1
如果:data=1000 0000 data=data>>2; data=0010 0000 == 32==data除以2^2
如果:data=1000 0000 data=data>>3; data=0001 0000 == 16==data除以2^3
......
如果:data=1000 0000 data=data>>6; data=0000 0010 == 2==data除以2^6
案例1:data为1字节 将data的第3,4为清0 其他位保持不变。
data= data & 1110 0111
1110 0111 == ~(0001 1000) == ~(0001 0000 | 0000 1000)
==~(0000 0001<<4 | 0000 0001<<3)
== ~(0x01<<4 | 0x01<<3);
data &= ~(0x01<<4 | 0x01<<3);//推荐
案例2:data为1字节 将data的第5,6为置1 其他位保持不变
data = data | 0110 0000
0110 0000==0100 0000 | 0010 0000==0000 0001<<6 | 0000 0001<<5
== 0x01<<6 | 0x01<<5
data |=(0x01<<6 | 0x01<<5);//推荐
案例3:data为1字节 将data的第3,4位清0, 5,6置1 其他位保持不变
data = data & ~(0x01<<3|0x01<<4) | (0x01<<5|0x01<<6);
int i=1;
int sum = 0;
while(i<=100)
{
if(i == 50)
continue;
sum += i;//sum = sum+i;
i++; }
cout<<sum<<endl;//没有结果 while是死循环 反复从i=1 开始
- 这里与Java不同的是没有方法是直接来获取数组的长度的
int arr[5] = {0} //推荐这样进行初始化
int length = sizeof(arr)/sizeof(arr[0]) // 获取数组的长度
//sizeof() 是用来获取数的占用字节数
sizeof(arr)/sizeof(arr[0]) //数组占用的总字节数/单个位置所占用的字节
//就是数组的长度
int arr[3][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4}};
int row = sizeof(arr)/sizeof(arr[0]); //获取行
int clo = sizeof(arr[0])/sizeof(arr[0][0]); //获取列
// 数组遍历
for(int i = 0 ;i<row ;i++){
for(int j = 0 ;j<clo ;j++){
cout<<arr[i][j];
}
}
int arr[3] = {0};//{0,0,0}
int arr2[2][3]={0} // {{0,0,0},{0,0,0}}
这下面可以不用看了:
//一维数组
int arr[4] = {1,2,3,4} //全部初始化
int arr[4] = {1,2,3} //部分初始化 {1,2,3,0}
int arr[]={10,20,30,40,50}; //元素个数由初始化个数决定
int arr[4]={0};//将第0个元素初始化为0 其他未被初始化自动补0 推荐
int arr[4]={10};//10 0 0 0
int arr[4]={[2]=10, [3]=30};//指定下标初始化 {0 0 10 30}
//二维数组
//分段初始化 (没有初始化到的默认为0)
int arr[3][4]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; //完全初始化 只能省略行数
int arr[][4]={ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };//完全初始化只能省略行数标
int arr[3][4]={ {1,2}, {5,6}, {9,10,11} };//部分初始化 其他值为0
//连续初始化
int arr[3][4]={ 1,2,3,4, 5,6,7,8, 9,10,11,12};//完全初始化
int arr[][4]={1,2,3,4, 5,6,7,8, 9,10,11,12}; //可以省略行数
int arr[3][4]={ 1,2, 5,6, 9,10,11};//部分初始化
案例:
int arr1[3][4]={ {1,2}, {5,6}, {9,10,11} };
int arr2[3][4]={ 1,2, 5,6, 9,10,11};
arr1[1][2] +arr2[1][2] == 11 // arr1[1][2] = 0 ;arr2[1][2] = 11
这是自学C++第一天 认为需要注意的知识点,目前还是和java很相似的,感觉还没到难点!