1. //C++学习笔记_01基础 2. #include <iostream> 3. #include <stdio.h> 4. #include <cstring> 5. #include <time.h> 6. using namespace std;//命名空间::默认使用这个命名空间中的函数 7. 8. void Print();//函数声明 9. 10. void TestBitOper()//位运算 11. { 12. int a=123; 13. int b=456; 14. 15. int c=a&b; 16. //与运算&: 把两个变量,按照二进制bit位,一位位的进行运算,得出结果的各个bit位的值 17. //道理类似于if(fun1()&&fun2()) fun1()和fun2()同时为true 才会进入分支 18. //把a和b用二进制表示(int变量占4个字节,也就是 32个bit位) 19. // a=(23个0) 0 01111011 20. // b=(23个0) 1 11001000 21. // &只有两边都是1,结果才是1,否则结果是0 22. // c=(23个0) 0 01001000 23. std::cout<<"与运算:"<<c<< std::endl; 24. 25. //或运算|:道理类似于 if(fun1()||fun2()) fun1()和fun2() 任意一个为true 就会进入分支 26. c=a|b; 27. // a=(23个0) 0 01111011 28. // b=(23个0) 1 11001000 29. // | 两边任意一个是1,结果就是1,同时为0结果才为0 30. // c=(23个0) 1 11111011 31. std::cout << "或运算:" << c << std::endl; 32. 33. //取反 ~: 把每个比特位0变1,1变0,道理类似于 if(!fun1()) 34. c=~a; 35. // a=(23个0) 0 01111011 36. // ~ 每个bit位反一下 37. // c=(23个1) 1 10000100 //注意:这是个负数(最高位是1) 38. //关于负数怎么看值:使用16进制表示 c = 0xFFFFFF84 39. //负数值:-c=0xFFFFFFFF-c+1(0xFFFFFFFF 就是 -1)=0x7C=124 40. //所以 c=-124 41. std::cout<<"取反运算:"<<c<< std::endl; 42. 43. //异或^: 两个bit位值相同,则结果是0,值不同,则结果是1 44. // 道理类似于if(a != b) 45. c=a^b; 46. // a=(23个0) 0 01111011 47. // b=(23个0) 1 11001000 48. // ^ 相等得0,相异得1 49. // c=(23个0) 1 10110011 50. std::cout<<"异或运算:"<<c<< std::endl; 51. 52. //左移运算 << 53. c=a<<1; 54. //把a的各个bit位,往高位移动1个位置,低位补0 55. //a=(23个0) 0 01111011 56. // << 每个bit位往高位移动 57. // c=(23个0) 0 11110110 58. std::cout << "左移运算:" << c << std::endl; 59. 60. //右移运算 >> 61. c=a>>1; 62. //把a的各个bit位,往低位移动1个位置,高位补0 63. // a=(23个0) 0 01111011 64. // >> 每个bit位往低位移动 65. // c=(23个0) 0 00111101 66. std::cout << "右移运算:" << c << std::endl; 67. 68. //举例:我们有 30盏灯(或者说30个标志),只有两种状态 开 或者 关 69. //我们可以用一个 int 来表示 30 个灯的开关状态 (每个灯占一个bit位) 70. //实际中的例子:LED 电子显示屏 动态显示一些 文字。显示的方法,就是 通过控制各个像素点灯的亮灭状态 71. //我们这里就以 30 盏灯为例 (从低位0到高位29,分别表示 0-29 这30个灯) 72. //通过bit位控制灯,1表示开,0表示关 73. //我们想 打开 第 N 栈灯 (把第N个bit位置为1) 74. //==》通过 或运算,就可以把这个bit置为1 (无论原来是0还是1) 75. int xxx = 75;//(1001011) 2 进制 76. 77. //把 xxx 的第 7 个bit位置为1 78. xxx|=(1<<7); 79. 80. //同样的把xxx的第 10个bit为置为0 81. xxx&=(~(1<<10)); 82. 83. //获取第20盏灯的开关状态 84. //先右移20个bit位,把这个开关状态移动到最低位,然后和1做与运算 85. xxx>>=20; 86. xxx&=1; 87. //或者与上第 20 bit位为1,其它bit位为0 的数 88. int yyy=xxx&(1<<20); 89. 90. //如果我们想把 第15盏灯的开关拨一次(开变关,关变开) 91. //无论0还是1,异或上0,它的值不变 92. //无论0还是1,异或上1,它的值变反 93. xxx^=(1<<15); 94. } 95. 96. //#define 代码需要写到同一行;\表示把代码连城一行 97. #define WriteLog(level, fmt, ...) \ 98. do{ \ 99. /*...*/ \ 100. }while(0) 101. 102. typedef struct tagList//结构体 结构体指针 103. { 104. int x; 105. struct tagList *pNext; 106. }List; 107. 108. //根据学生成绩给学生评价 80~100优秀 70~80良 60~70中 60以下差 109. void TestProcess(int score) 110. { 111. int x=score/10; 112. switch(x) 113. { 114. case 10: 115. case 9: std::cout<<"发奖状"<<std::endl;//这里不写break 116. case 8: std::cout<<"优秀"<<std::endl;break; 117. case 7: std::cout<<"良好"<<std::endl;break; 118. case 6: std::cout<<"中等"<<std::endl;break; 119. default: std::cout<<"差等"<<std::endl; 120. } 121. 122. for(int i=0;i<10;i++){ //使用索引 123. //do something 124. } 125. 126. x=0; 127. while(x<10){ 128. x++; 129. //do something 130. } 131. 132. List *p=(List*)malloc(sizeof(List)); 133. p->x=0; 134. p->pNext=NULL; 135. //给链表p 增加节点 136. while(p->pNext){ //遍历链表 137. p=p->pNext; 138. //do something 139. } 140. 141. while(x){ 142. //对x做某个一系列操作 143. } 144. while(0){ 145. //这里的代码将不会执行 146. } 147. while(1){//退出循环的条件比较多比较复杂的情况,在内部调用break来退出 148. //... 149. if(x) break; 150. } 151. 152. do{ 153. //这里的代码至少被执行一次 154. }while(x); 155. do{ 156. //这里的代码只执行一次 157. } while(0); 158. 159. double pi=3.1415926; 160. int a=pi; //隐式转换:默认会把pi取整后,赋值给y==>y=3 161. int b=(int)pi;//显式转换:C语言一般使用这种转换 162. b=static_cast<int>(pi);//显式转换:C++要求大家使用这个方式进行转换,更加严格安全 163. 164. return ; 165. } 166. 167. int g_flag=0; //默认值为0 168. //局部变量:定义在函数内部的变量(只能在函数内使用,函数执行完成,变量就会被销毁) 169. // 这些变量存在栈内存中(函数调用时候产生栈存储变量和运行环境) 170. // 栈内存是有限的,所以,我们不要在局部变量中定义占空间太大的变量(比如占1M内存的变量) 171. // 变量太大,可能会导致栈溢出 172. // 如果要用到这么大的内存,一般使用申请内存的方式 173. // 局部变量不初始化的话,他的值是随机的,不确定的 174. //全局变量:定义在函数外部 (如g_flag), 这个变量,在本文件所有函数中,都可以使用 175. // 别的文件使用 extern int g_flag 声明这个变量后,别的文件也可以使用它 176. // 所有函数公用 177. // 全局变量的默认值是0 178. //全局变量和局部变量,变量名可以重复 179. 180. void TestVariable()//全局变量和局部变量 181. { 182. //int arr[100000000];不允许定义这么大内存的数组 183. int g_flag=100; 184. std::cout<<g_flag<<std::endl; //优先使用局部变量 185. 186. for(int i=0;i<10;i++){//这个i的生效范围,只在for循环中 187. std::cout<<i<<" ";//for循环结束后,这个i就没了 188. } 189. 190. int i; 191. for(i=0;i<10;i++){ 192. std::cout<<i<<" "; 193. } 194. std::cout<<i<<std::endl; 195. 196. // {}内部定义的变量.只在{}内存在,出来之后,这个变量就没了 197. { 198. int xxx=0; 199. std::cout<<xxx<<std::endl; 200. }//这称之为一个程序块 201. //std::cout<<xxx<<std::endl; 不能输出 202. 203. int arr[10]={1,2,3,4,5,6,7,8,9,0 }; 204. for(i=0;i<10;i++){ 205. int x =arr[i]; //这个x只在for循环中有效 206. //.... 207. } 208. //定义arr[10] 事实上,我们只定义了一个变量,arr 209. //地址:就是一个数字,这个数字标志 数据到底存在内存的哪个地方 210. //地址这个值 对应的变量,就是指针(这个变量存储的值是一个地址,也就是数据的存储位置) 211. //这个地方,我们的arr事实上就是一个指针,存储的是arr中第一个元素的位置 212. //那么arr+1,arr+2,... 就表示:第二个,第三个,... 等元素的地址 213. //我们使用*arr来访问某个地址指向的变量值 214. //访问arr中的元素 可以使用 *arr,*(arr+1),*(arr+2), .... 215. //当然,我们也可以使用 arr[0],...,arr[9]进行访问 216. //数组使用注意点:不要越界。比如访问 arr[10] 217. 218. //另一种指针:申请内存的方式得到的指针 malloc 219. char *pStr; //pStr 是我们函数的局部变量,他的值就是一个随机值 220. //变量类型是 指针(指向的是一个字符串),占用4个字节 221. // 内存地址使用4个字节的数字进行表示 222. pStr=(char*)malloc(10000); 223. //malloc:在堆内存中,划10000个字节的内存出来, 224. //然后把这片内存的起始地址 返回出来,赋值给 pStr 225. //现在,pStr的值,是一个地址,这个地址是堆内存中的地址 226. // 这个地址所在的内存,函数退出时候是不会自动消失。 227. // 直到我们主动调用free(pStr) 释放掉它 228. // *pStr 表示的是这个地址里面存储的值 229. 230. strcpy(pStr,"Hello world"); 231. for(i=0;i<20;i++){ 232. std::cout<<*(pStr+i)<<" "; 233. } 234. std::cout<<std::endl; 235. 236. printf("pStr-:%s\n",pStr); 237. std::cout<<"*pStr:"<<pStr<< std::endl; 238. //*pStr 等价于 pStr[0] 239. //如果我们想输出 pStr 的值(也就是地址) 240. printf("地址:%p\n", pStr); 241. std::cout<<pStr<<std::endl; 242. std::cout<<"地址:"<<static_cast<void *>(pStr)<<std::endl; 243. 244. free(pStr);//最后,我们需要释放内存 245. } 246. 247. //函数重载:允许定义多个同名函数。 248. //两个函数重名,但是,入参不一样 (可以是参数类型不一样,也可以是参数个数不一样,也可以类型个数都不一样) 249. //调用函数的时候,会自动识别变量类型和个数,来调用对应的函数。 250. //不能使用返回值来区分,(调用的时候,通过入参,不知道要调用哪一个) 251. void Print(int x){ 252. std::cout<< "My Value is "<<x<< std::endl; 253. } 254. /* 255. int Print(int y) { 256. //入参类型和个数一样,返回值不一样,不允许 257. } 258. */ 259. void Print(int x, int y){ 260. std::cout << "Pair Value is (" << x << ", " << y << ")" << std::endl; 261. } 262. void Print(char str[]){ 263. std::cout << "My name is " << str << std::endl; 264. } 265. 266. int main(int argc, char *argv[]) 267. { 268. //TestBitOper(); 269. TestVariable(); 270. 271. Print(10); 272. Print(1, 2); 273. Print("Jack"); 274. 275. char szName[12]; 276. printf("Your Name:"); 277. scanf("%s",szName); 278. //fopen_s(); 279. printf("Hello %s\n", szName); 280. 281. //cout 标准输出 282. //cin 标准输入 283. //endl 换行 284. std::cout << "\n---------- C++ ------------\n"; 285. std::cout << "Your Name again:"; //相当于printf("Your Name again:"); 286. std::cin >> szName; //相当于 scanf("%s", szName); 287. std::cout << "Again " << szName << std::endl; 288. 289. Print();//函数调用 290. 291. //C++运算 292. int a = 10; 293. int b = 3; 294. int c = a + b;//a-b; a*b; a/b 295. int d = a % b; //取余(求模) :a 整除 b 后的余数 (必然小于 b) 296. // a < b 的话, a % b == a (10 除以 20, 商 0 ,余 10) 297. //求余运算用的多的地方:比如,获取随机数 298. srand(time(NULL)); 299. int x = rand(); 300. std::cout << "随机数:" << x << std::endl; 301. //如果我们想生成一个 0 - 10 之间的随机数 ? 302. x = rand() % 11; 303. std::cout << "随机数:" << x << std::endl; 304. //如果我们想生成 5 - 10 之间的随机数 ? 305. x = 5 + rand() % 6; // 6 就是 10 - 5 + 1 306. 307. //a += b 等价于 a = a + b 308. //同样的有 a -= b ; a *= b; a /= b; a %= b; 309. //效率: a += b 比 a = a + b 高 310. 311. system("pause"); 312. return 0; 313. } 314. 315. void Print(){ 316. std::cout << "This is my first program!" << std::endl; 317. }