C语言基础
2019-02-07 本文已影响0人
无尾树袋熊
- c语言是由函数组成的
- 先要执行main函数固定格式 :
- int main(){
return 0 ;
- }
- ()是函数的标示,{}函数管辖的范围。
注意点
- 函数名不可重复
- 要执行一个定义好的函数,需要在main函数中调用。格式:函数名();
-
include<stdio.h>查找系统定义的函数
- c语言中的main函数写法多,标准写法如上
- 多行注释不能嵌套多行注释/* */
- 注释应用场景:思路分析,函数变量说明
C基础
一、关键字
- 保留字,指一些被被赋予特殊含义的单词,一共有32个
- 不能作为函数和变量的名称
二、标识符
- 程序员在程序中给函数、变量等起的名字就是标识符.目的是将某些东西区分开
- 命名规则:
- 只呢由字母,下划线,数字组成
- 不能以数字开头
- 不能是关键字
- 严格区分大小写
- 命名规范:
- 见名知意,驼峰命名:方便阅读
三、C语言常量和变量
- 数据的分类:静态,动态
常量:固定的数据
整型常量(整数)
实型常量(小数)
- 单精度(例如:10.12f 或 10.12F)
- 双精度(默认都为双精度)
字符型常量
- 字符型常量的 ''中只能放一个字符(例: 'a' '1')
- 特殊情况:转移字符除外('/t' '/n' '//')
字符串型常量
- 可以放一个或多个字符("123" "你好")
- 系统会在末尾加上一个字符 '\0'作为结束标志
变量:可以改变的数据
定义变量: 数据类型 变量名1,变量名2;
- 为什么指定数据类型:1.告诉系统,定义的变量对应的储存空间中,将来能够存储怎样的数据 2. 告诉系统需要分配多大的存储空间
- 为什么指定变量名:为了找到开辟好的存储空间,并使用
- 要使用变量,必须先初始化.否则变量中保存的都是一些垃圾数据
- 变量输出:printf("变量名 = %i " ,变量名) 其中%i是占位符,int
变量的作用域
局部变量:定义在{}内的
- 作用域:从定义变量的一行开始,直到}或return为止
全局变量:定义在{}内外的
- 作用域:从定义变量的一行开始,直到文件末尾
注意点
- {}会新开辟一段存储空间
- 局部变量:在同一个作用域内,不能出现同名变量.不同作用域可以出现同名变量
- 全局变量:相同作用域,可以出现同名变量
四、printf和scanf函数
printf函数:
- 把指定的数据显示在屏幕上
格式:
- printf("输出的内容");
- printf("格式化字符串",输出列表项);
- 格式化字符串:%[标示][输出宽度][.精度][长度]类型
- %i,%d:整型常量和变量 %f:单精度小数 %lf:双精度小数 %c:字符型常量变量
输出宽度格式:
指定输出内容位数 。如果输出内容大于或等于指定的宽度,则按照实际输出的宽度输出。如果如果输出内容小于指定的宽度,则在实际输出的内容前添加空格
标志格式:
- -左对齐,默认右对齐
- +当输出值为正时,添加一个+号,默认不显示
- 0右对齐时,用0填充宽度,默认用空格(常用在日期格式上)
- 空格 输出值为正时,在前面加上空格,为负数加上负号
精度格式:
指定输出小数位数保留
- 其它格式: %[.]类型(为占位符)
Scanf函数:
用于接受键盘输入的内容,是一个阻塞式函数
格式:
- scanf("格式化字符串",地址列表);
- &取地址符号: &变量名
注意点:
- 单精度的小数,有效位数只有6-7位,超出后则为垃圾数据(有效位数是从小数点前开始计算)
- 双精度的小数,有效位数只有15-16位,超出后则为垃圾数据
- scanf如果接受的不是字符类型的数据.输入的空格,TAB,回车都是无效的
- scanf函数的格式化字符串不能以\n结尾,不然永远无法结束
- ==scanf函数的格式化字符串中还有别的字符串,必须要原样输入==
- scanf函数如果需要接受多个非字符类型的数据,可以通过空格,TAB,回车作为分隔符
- 清空输入缓冲区:
- fflush(stdin);不能跨平台
- setbuf(stdin,NULL);
五、C语言运算符
告诉程序执行特定算数或逻辑操作的符号
- 操作数:参与运算的数
- 表达式:利用运算符链接在一起的有意义,有结果的语句
(1)算数运算符
- 加减乘除:+ - * /
(2)类型转换
1.自动类型转换
1.运算转换
小类型转大类型:int -> double(大小一样才能运算,编译器自动转换)
2.赋值转换
例:
int num = 3.14;
printf("num = %i\n",num)
2.强制类型转换
例:
double c = 3.33;
int d = c;
(2)赋值运算符
1.简单赋值运算符
= 将右边的值赋值给左边的变量
- 右结合性
2.复杂赋值运算符
+= -= *= /= %=
例:
b += 5; //b = b + 5;
b -= 5; //b = b - 5;
b *= 5; //b = b * 5;
b %= 5; //b = b % 5;
3.赋值运算符结合性
1.右结合性
int b = 10;
b += 10 -5;// b = b + (10 - 5);
2.优先级
赋值运算的优先级 低于 算数运算符
(3)自增自减
快速加减1 例:
int num = 1;
num++; // num--;后加减
++num; // --num;先加减
比较:
int num = 10;
int res = 10 + num++; //res = 20,num = 11;
int res = 10 + ++num; //res = 21,num = 11;
- 可以用于字符型变量.例:
char ch = "m";
ch++;
printf("ch = %c\n",ch);//ch = e
(4)sizeof运算符
1.格式:
- sizeof(变量/常量/数据类型);
int res = sizeof(3.14);
int res = sizeof(double);
int res = 10;
int res = sizeof(res);
//数据类型不能省略圆括号
- sizeof 变量/常量;
2.作用:
用于计算变量/常量/数据类型占用的存储空间
(5)逗号运算符
- 用于简化代码
- 有运算结果
- 结果是最后一个表达式的值.例:
int a,b,c;
a = 10,b = 20,c = 30;
int res = ((a + b),(a + c));// res = 40 面试常用
(6)关系运算符
- != == <= >= > <
- 返回值:0 或 1
- 非0即真.只有0是假
int a,b;
a = 10 ,b = 5;
int res = a > b;//res = 1
int res = a < b;//res = 0
(7)逻辑运算符
1.逻辑与 &&
- 格式:表达式&&表达式
- 一假则假 例:
int res = (10 > 5)&&(20 > 19);//res = 1
int res = (10 > 11)&&(20 > 19);//res = 0
2.逻辑或 ||
- 格式:表达式&&表达式
- 一真则真 例:
int res = (10 > 11)||(20 > 21);//res = 0
int res = (10 > 11)||(20 > 19);//res = 1
3.逻辑非 !
- 格式: !表达式
- 真为假,假为真 例:
int res = !(10 > 9);//res = 0
int res = !(10 < 9);//res = 1
4.逻辑运算符结合性
- && ||左结合性
- 逻辑短路,只要第一个假,第二个表达式则不会运行.例:
int num = 1;
int res = (10 > 20)&&(++num > 0);
//res = 1 num = 1 一假则假
int num = 1;
int res = (10 < 20)||(++num > 0);
// res = 1 num = 1 一真则真
- !右结合性
- 可以连续非非非.例:
int res = !!!(10 > 9);//res = 0
(8)三目运算符
- 格式:表达式? 结果A : 结果B;
- 表达式为真,返回A;为假,返回B.例:
int a = 10 , b = 5;
int res = a > b ? a : b;//res = 10
- ?:不能分开使用
- 三目运算符优先级低于算数运算符
注意点:
- 在+ - * /的运算中,整数和整数的运算结果一定是整数.整数和小数的运算结果一定是小数
- 在%中不能出现小数
- 在%中被除数为0,结果就为0
- 在%中,结果的正负性,取决于被除数
- 自动类型转换不会改变原有量的值
- 自增自减只能用与变量
- 自增自减最好单独出现.例如:
int num = 10;
int res = 10 + num;
num++;
- 同一个表达式同一个变量同时自增自减,没有规定怎么运算,不同编译器结果不一样
- sizeof优先级高于算数运算符
- 关系运算符是左结合性(无法判断某个值是否在某个区间内).例:
int res = 10 > 5 > 3;//res = 0
- <= < > >= 优先级高于 == !== ==先优先级后结合性==.例:
int res = 10 == 10 > 9;//res = 0
五、流程控制
- 分为顺序结构,循环结构,选择结构
(1)if选择结构
格式:
if(条件表达式){
条件成立执行语句
}
其它语句
if(条件表达式){
条件成立执行语句
}else{
条件不成立执行语句
}
if(条件表达式){
条件成立执行语句
}else if(条件表达式){
条件成立执行语句
}else if(条件表达式){
条件成立执行语句
}else{
条件不成立执行语句
}
if可以相互嵌套
(2)switch选择结构
格式:
switch(表达式){
case 表达式1:
被表达式1控制的语句;
break;
case 表达式2:
被表达式2控制的语句;
break;
default:
被default控制的语句;
break;
}
- case穿透问题
- switch中只要有一个被匹配了,其它的case和default就会失效.(break的作用就是结束当前的switch语句)
- default==写在最后==,default后的break可以省略
- default书写位置可以随便写(尽量写在最后)
- switch后()里只能放表达式/变量/常量,并且是整型或能被提升为整型.例:
switch(num)
switch(2)
switch(1 + 1)
switch(1.1) //报错,小数不能被提升为整型
switch('a') //char本质为int类型
- switch的case后面只能放常量/表达式,并且是整型或能被提升为整型.例:
case num //报错
- switch的case的值不能重复
switch(2){
case 1:
case 1://会报错
}
- case后不能定义变量,要定义必须加上{}.(作用域混乱)例:
switch(1){
case 1:
int num = 666;//会报错
}
switch(1){
case 1:{
int num = 666;//没问题
}
}
(3)循环结构
1.while
- 格式:
while(条件表达式){
条件满足才执行的代码
}
- 应用场景:企业开发中,某些代码需要重复执行的,就用while
- 累加思想:定义变量记录每次的和
while (i <= num) {
res = res + i;
i++;
}
2.dowhile
do{
被控制的语句
}while(条件表达式);
//先执行,再判断
-应用场景:验证
3.for
- 格式
for(初始化表达式;条件表达式;循环后增量表达式){
被控制的语句;
}
- 初始化表达式在循环执行过程中只会执行一次
(4)跳转语句
1.break
- 只能用在switch和循环结构中, 离开应用的范围没有任何意义
- 作用是跳出循环语句 while , dowhile,,for,switch
- 如果循环嵌套的时候,break只会跳出所在(最近的)的循环
- 不能离开应用范围,不然会报错.例:
if(1){
printf("随便写点东西\n");
break;
// 离开应用范围后会报错
}
2.continue
- 只能用在循环中,离开应用范围没有任何意义
- 作用:跳过本次循环,进入下一次循环
- 不能离开应用范围,不然会报
- 如果循环嵌套的时候,continue只会跳出所在(最近的)的循环
3.goto
- 只能用于在同一个函数中跳转, 可以往前往后跳,只要是在同一个函数中
- goto需要配合标签使用(标签可以是任意的名称后面加上:).例:
printf("第一行代码\n");
goto lnj;
printf("第二行代码\n");
lnj: printf("第三行代码\n"); //直接执行
- 一般不使用
注意点
- if结构中只有一个{}中的语句会被执行
- if省略大括号后只有紧随其后的那条语句才受控制(else只与最近的没有被匹配的if匹配)
- {}单独出现代表的是一个代码块.例;
int num = 10;
{
int num = 18;
printf("%i\n",num);//18
}
printf("%i\n",num);// 10
- 如果if/while省略了{},那么后面不能再定义变量(作用域混乱)
int num = 18;
if(num >= 18)
int num = 666;
printf("开网卡");
//看起来num的作用域是从定义的一行到return或}为止.但实际上num只有在if条件满足时才会执行,两者冲突.
- 任何值都有真假性
- 企业开发中一定不要用==来判断两个小数是否相等,可能会出现精度问题(建议使用 >= <=)
- 排序问题:两两比较后,最值会出现在最后
- 企业开发中能用if用if
- while省略大括号后只有紧随其后的那条语句才受控制
- while/if,任何值都有真假性,都可以嵌套其它合法代码
- 用于控制while的变量在循环的内部外部都可以使用.控制for的变量只能在循环内使用(企业开发中,能用for就用for)
- for和while都可以省略大括号.(省略后只能控制紧随其后的语句,且不能定义变量)
- 在企业开发中一般情况下,循环嵌套不会超过两层, 最多不超过三层
- 规律:循环嵌套的时候,外循环控制行数, 内循环控制列数
- 在企业开发中,但凡遇到需要解决很多行很多列的问题, 就要想到循环嵌套
六、函数
- 优点:提高了代码的复用性,有利于维护
- 作用:将某些代码封装起来
- 格式:
返回值类型 函数名称(形参列表){
被封装到函数中的代码;
}
(1)如何定义函数
- 确定形参列表(告诉调用者调用时是否需要传递一些辅助的数据)
- 确定返回值和返回值类型(返回的数据是什么类型, 返回值类型就写什么类型)
- return的作用之一就是将后面的数据返回给函数的调用者.例:
int getMax(int num1, int num2){
int max = num1 > num2 ? num1 : num2;
return max;
}
int main(){
int a = 10,b = 20;
int res = getMax(a,b);
printf("res = %i\n",res);//20
}
(2)函数声明
- 如果将函数定义在调用之后,必须在调用前编写函数声明.
- 函数声明;在调用前告诉编译器,我有一个名称叫什么,接受什么==类型参数,返回值==是什么.
voide test{};
int main(){
test ();
return 0;
}
viode test(){
printf("test\n");
}
- 函数的声明可以声明多次,但函数只实现一次
- 返回值是int类型,可以不用编写函数声明(了解)
- 函数声明必须写在调用之前
(3)main函数
- main函数是系统自动调用的函数,不能手动调用
- 系统调用main函数时,默认会传递两个参数:
int main (int argc,const char *argv[]){
}
//argc:第二个数组保存数据的个数
//argv:默认保存了一个数据:当前文件的地址.并且可以动态的添加数据
//默认情况下,调用main函数时,回给argv这个数组中存放一个元素
- return 0;目的是告诉系统是正常结束的
(4)函数补充
1.分类
- 没有返回值,没有形参
- 没有返回值,有形参
- 有返回值,没有形参
- 有返回值,有形参
2.注意点
- 如果没有写函数返回值类型,默认为int
- 如果实际返回值和指定返回值类型不同,会转换为指定返回值类型
(5)递归函数
- 自己调用自己:可以实现循环的功能,但性能比循环差很多.例:
//求n的阶乘:
int factorial();
int main()
{
int n = -1;
printf("请输入一个数n = ?按回车键结束\n");
scanf("%i",&n);
setbuf(stdin,NULL);
int res = factorial(n);
printf("res = %i\n",res);
return 0;
}
int factorial(int num){
if(num == 1){
return 1;
}else{
return factorial(num - 1)*num;
}
}
- 企业开发中,一般情况下,不会使用递归.在面试或文件操作(遍历目录)中出现较多
注意点:
- 函数可以有参数,也可以没有参数.函数的参数可以是零个或多个.
int sum(int a, int b){
return a + b;
}
- 函数可以有返回值,也可以没有返回值(如果函数没有返回值, 那么返回值类型写void).例:
void test(){
printf("test\n");
}
- (即使返回值类型,形参列表不同)函数的==名称也不能相同==
- 函数不能嵌套定义
- 如果是==基本类型的数据==(int,char,float,double)作为函数的参数,那么在函数内修改形参,不会影响外面实参的值
- 在函数内部不能定义和形参同名的变量
七、进制和位运算
(1)进制
- 一种计数的方式
- 如果用16进制,前面加上0x(%x 输出)
- 如果用8进制,前面加上0(%0 输出)
- 如果用2进制,前面加上0b
1. 2进制转8进制
- 例如:将二进制01100100转换为八进制数
从右至左每3位划分为8进制的1位, 不够前面补0
001 100 100
第0位: 100 等于十进制 4
第1位: 100 等于十进制 4
第2位: 001 等于十进制 1
最终结果: 144就是转换为8进制的值
2. 2进制转16进制
- 例如: 将二进制01100100转换为十六进制数
从右至左每4位划分为16进制的1位, 不够前面补0
0110 0100
第0位: 0100 等于十进制 4
第1位: 0110 等于十进制 6
最终结果: 64就是转换为16进制的值
3. 其它进制转换为十进制
101101 = (1 * 2 ^ 5) + (0 * 2 ^ 4) + (1 * 2 ^ 3) + (1 * 2 ^ 2) + (0 * 2 ^ 1) + (1 * 2 ^ 0)
= 32 + 0 + 8 + 4 + 0 + 1
= 45
016 = (0 * 8 ^ 2) + (1 * 8 ^ 1) + (6 * 8 ^ 0)
= 0 + 8 + 6
= 14
0x11f = (1 * 16 ^ 2) + (1 * 16 ^ 1) + (15 * 16 ^ 0)
= 256 + 16 + 15
= 287
4.十进制快速转换为其它进制
十进制 --> 二进制
100 --> 1100100
100 / 2 = 50 0
50 / 2 = 25 0
25 / 2 = 12 1
12 / 2 = 6 0
6 / 2 = 3 0
3 / 2 = 1 1
1 / 2 = 0 1
十进制 --> 八进制
100 --> 144
100 / 8 = 12 4
12 / 8 = 1 4
1 / 8 = 0 1
十进制 --> 十六进制
100 --> 64
100 / 16 = 6 4
6 / 16 = 0 6
5. 十进制小数转换为二进制小数
- 整数部分,直接转换为二进制即可
- 小数部分,使用"乘2取整(小数部分为0),顺序排列
// 整数部分(除2取余)
12
/ 2
------
6 // 余0
/ 2
------
3 // 余0
/ 2
------
1 // 余1
/ 2
------
0 // 余1
//12 --> 1100
// 小数部分(乘2取整数积)
0.125
* 2
------
0.25 //0
0.25
* 2
------
0.5 //0
0.5
* 2
------
1.0 //1
0.0
// 0.125 --> 0.001
// 12.8125 --> 1100.001
6. 二进制小数转换为十进制小数
- 整数部分按照二进制转十进制即可
小数部分从最高位开始乘以2的负n次方, n从1开始
// 整数部分(乘以2的n次方, n从0开始)
0 * 2^0 = 0
0 * 2^1 = 0
1 * 2^2 = 4
1 * 2^3 = 8
// 1100 == 8 + 4 + 0 + 0 == 12
// 小数部分(乘以2的负n次方, n从0开始)
0 * (1/2) = 0
0 * (1/4) = 0
1 * (1/8) = 0.125
// .100 == 0 + 0 + 0.125 == 0.125
// 1100.001 --> 12.125
7.原码反码补码
- 计算机只能识别0和1,所以计算机中存储的数据都是以0和1的形式存储的
- 数据在计算机内部是以补码的形式储存的, 所有数据的运算都是以补码进行的
- 正数的原码、反码和补码都是它的二进制.例12:
0000 0000 0000 0000 0000 0000 0000 1100
0000 0000 0000 0000 0000 0000 0000 1100
0000 0000 0000 0000 0000 0000 0000 1100
- 负数的原码、反码和补码:
- 二进制的最高位我们称之为符号位,最高位是0代表是一个正数,最高位是1代表是一个负数
- 一个负数的原码,是将该负数的二进制最高位变为1
- 一个负数的反码,是将该数的原码除了符号位以外的其它位取反
- 一个负数的补码, 就是它的反码 + 1
- 例:-12的原码,反码,补码:
0000 0000 0000 0000 0000 0000 0000 1100 //12二进制
1000 0000 0000 0000 0000 0000 0000 1100 //-12原码
1111 1111 1111 1111 1111 1111 1111 0011 //-12反码
1111 1111 1111 1111 1111 1111 1111 0100 //-12补码
- 为什么要引入反码和补码
- 计算机只能做加法运算,不能做减法和乘除法,所有的减法和乘除法内部都是用加法来实现的
- 对于减法来说,如果使用原码结果是不正确的, 所以才引入了反码
- 对于0来说,前面的负号没有任何意义, 所以才引入了补码
- 由于int只能存储4个字节,也就是32位数据,而计算的结果又33位,所以最高位溢出了,符号位变成了0,所以最终得到的结果是0.例:
// 1 - 1; 1 + (-1);
0000 0000 0000 0000 0000 0000 0000 0001 // 1补码
1111 1111 1111 1111 1111 1111 1111 1111 // -1补码
---------------------------------------
10000 0000 0000 0000 0000 0000 0000 0000 // 计算结果补码
0000 0000 0000 0000 0000 0000 0000 0000 // == 0
(2)位运算
1. & 按位与
- 规则: 一假则假
- 规律: 任何一位和1相与,结果还是原来的那一位
9 & 3 = ?
0000 0000 0000 0000 0000 0000 0000 1001 // 9的补码
0000 0000 0000 0000 0000 0000 0000 0011 // 3的补码
-----------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0001 // 1
2. | 按位或
规则: 一真则真
0000 0000 0000 0000 0000 0000 0000 1001 // 9的补码
0000 0000 0000 0000 0000 0000 0000 0011 // 3的补码
-----------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1011
3. ~ 按位取反
规则: 真变假, 假变真
4. ^ 按位异或
- 规则: 相同为0, 不同为1
0000 0000 0000 0000 0000 0000 0000 1001 // 9的补码
0000 0000 0000 0000 0000 0000 0000 0011 // 3的补码
-------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1010 // 10
- 规律:
- 任何两个相同的值异或之后的结果都是0
- 任何一个数和0异或之后的结果还是那个数
- 任何一个数异或另外一个数两次之后, 结果还是那个数
- 应用场景:简单的加密
int pwd = 123456789;
int res = pwd ^ 998;
printf("加密之前: %i\n", pwd);
printf("加密之后: %i\n", res);
int res2 = res ^ 998;
printf("解密之后: %i\n", res2);
return 0;
5. << 按位左移
- 乘以2的n次方
- 移动规则:从符号位开始整体移动, 多余的砍掉, 缺少的用零补
- 计算规律: 一个数左移几位就是 这个数乘以2的多少次幂(9 * 2(1) = 18,9 * 2(2) = 36)
9 << 1
0000 0000 0000 0000 0000 0000 0000 1001 // 位置参考
000 0000 0000 0000 0000 0000 0000 10010 // 9的补码
- 应用场景:==在企业开发中一旦想要某个数乘以2的多少次幂, 就要想到左移==
5. >> 按位右移
- 除以2的n次方
- 移动规则:除符号位以外整体右移,多出来的砍掉, 缺少的用符号位填充.例:
1000 0000 0000 0000 0000 0000 0000 1001 // -9源码
1111 1111 1111 1111 1111 1111 1111 0110 // -9反码
1111 1111 1111 1111 1111 1111 1111 0111 // -9补码
//右移后
11111 1111 1111 1111 1111 1111 1111 011 //补码
11111 1111 1111 1111 1111 1111 1111 010 // 右移完毕的结果, 反码
10000 0000 0000 0000 0000 0000 0000 101 // 右移完毕的结果, 源码
- 输入整数,==输出二进制==:
void printBinary(char value){
// int 4 --> 32
// char 1 --> 8
// 在企业开发中 , 数字我们称之为魔鬼
int len = sizeof(value) * 8;
for(int i = 0; i < len; i++){
int temp = (value >> (len - 1 - i)) & 1;
printf("%i", temp);
if(((i+ 1) % 4) == 0){
printf(" ");
}
}
注意点:
- 变量的内存是连续的
- 内存地址从大到小(只要定义变量,就会开辟内存空间)
- 计算机会从内存地址大的开始分配内存(内存寻址从大到小)也就是说先定义的变量内存地址大于后定义的变量
- 由于内存寻址是从大到小,所以存储补码也是从大到小(也就是从高位开始存储)
//高位 --> 低位
00000000 00000000 00000000 00001001
- ==变量的地址是所占用内存空间最小的那个地址==
类型说明符
- 一般用于修饰int类型的
- 说明长度的:
short int//2个字节
long//32位编译器中4个字节,64位8个字节
long long//8个字节
- 注意点:
- 如果存储的数据超出了类型对应的取值范围,那么就会导致存储的数据不对
- 由于内存非常有限,所以在编写程序的时候, 尽量合理的定义变量
- 由于说明长度的类型说明符一般都是用于说明int类型的,所以在使用的时候可以省略int:
short num1 = 123; // short == short int
long num2 = 123; // long == long int
- 说明符号位的
- unsigned 无符号的:
- 注意点:
- 不把二进制的第一位当做符号位来使用,所以只能存储零和正数,不能存储负数
- 如果变量被unsigned修饰了,那么取出的时候必须使用%u,%u就代表用无符号的方式取出
- 应用场景:存储银行存款,学生的分数等不能出现负数的情况
- signed 有符号的:
- 默认int就是有符号的,就可以保存负数,零,正数,所以signed一般用不上
注意点:
- c语言的rand函数是一个伪随机数.(生成随机数)例:
//先导入:#include();
srand(time(NULL));//种一个种子
int res = rand();
- 三目是一个运算符,所以必须有结果(结果A和结果B的位置放的必须是变量,常量, 表达式)(如果放的是一个函数, 那么这个函数必须有返回值)
- 企业开发中,尽量不要写数字
- %p是专门用于输出变量地址的
- &是专门用于取出变量地址
- C语言的规则:不看怎么存只看怎么取