C语言基础

  • c语言是由函数组成的
  • 先要执行main函数固定格式 :
  • int main(){
  • return 0 ;
    
  • }
  • ()是函数的标示,{}函数管辖的范围。

注意点

  1. 函数名不可重复
  2. 要执行一个定义好的函数,需要在main函数中调用。格式:函数名();
  3. include<stdio.h>查找系统定义的函数

  4. c语言中的main函数写法多,标准写法如上
  5. 多行注释不能嵌套多行注释/* */
  6. 注释应用场景:思路分析,函数变量说明

C基础

一、关键字

  • 保留字,指一些被被赋予特殊含义的单词,一共有32个
  • 不能作为函数和变量的名称

二、标识符

  • 程序员在程序中给函数、变量等起的名字就是标识符.目的是将某些东西区分开
  • 命名规则:
  1. 只呢由字母,下划线,数字组成
  2. 不能以数字开头
  3. 不能是关键字
  4. 严格区分大小写
  • 命名规范:
  1. 见名知意,驼峰命名:方便阅读

三、C语言常量和变量

  • 数据的分类:静态,动态

常量:固定的数据

整型常量(整数)
实型常量(小数)
  1. 单精度(例如:10.12f 或 10.12F)
  2. 双精度(默认都为双精度)
字符型常量
  1. 字符型常量的 ''中只能放一个字符(例: 'a' '1')
  2. 特殊情况:转移字符除外('/t' '/n' '//')
字符串型常量
  1. 可以放一个或多个字符("123" "你好")
  2. 系统会在末尾加上一个字符 '\0'作为结束标志

变量:可以改变的数据

定义变量: 数据类型 变量名1,变量名2;
  • 为什么指定数据类型:1.告诉系统,定义的变量对应的储存空间中,将来能够存储怎样的数据 2. 告诉系统需要分配多大的存储空间
  • 为什么指定变量名:为了找到开辟好的存储空间,并使用
  • 要使用变量,必须先初始化.否则变量中保存的都是一些垃圾数据
  • 变量输出:printf("变量名 = %i " ,变量名) 其中%i是占位符,int
变量的作用域
局部变量:定义在{}内的
  • 作用域:从定义变量的一行开始,直到}或return为止
全局变量:定义在{}内外的
  • 作用域:从定义变量的一行开始,直到文件末尾

注意点

  1. {}会新开辟一段存储空间
  2. 局部变量:在同一个作用域内,不能出现同名变量.不同作用域可以出现同名变量
  3. 全局变量:相同作用域,可以出现同名变量

四、printf和scanf函数

printf函数:

  1. 把指定的数据显示在屏幕上
格式:
  1. printf("输出的内容");
  2. printf("格式化字符串",输出列表项);
  3. 格式化字符串:%[标示][输出宽度][.精度][长度]类型
  4. %i,%d:整型常量和变量 %f:单精度小数 %lf:双精度小数 %c:字符型常量变量
输出宽度格式:

指定输出内容位数 。如果输出内容大于或等于指定的宽度,则按照实际输出的宽度输出。如果如果输出内容小于指定的宽度,则在实际输出的内容前添加空格

标志格式:
  1. -左对齐,默认右对齐
  2. +当输出值为正时,添加一个+号,默认不显示
  3. 0右对齐时,用0填充宽度,默认用空格(常用在日期格式上)
  4. 空格 输出值为正时,在前面加上空格,为负数加上负号
精度格式:

指定输出小数位数保留

  1. 其它格式: %[.]类型(为占位符)

Scanf函数:

用于接受键盘输入的内容,是一个阻塞式函数

格式:
  1. scanf("格式化字符串",地址列表);
  2. &取地址符号: &变量名

注意点:

  1. 单精度的小数,有效位数只有6-7位,超出后则为垃圾数据(有效位数是从小数点前开始计算)
  2. 双精度的小数,有效位数只有15-16位,超出后则为垃圾数据
  3. scanf如果接受的不是字符类型的数据.输入的空格,TAB,回车都是无效的
  4. scanf函数的格式化字符串不能以\n结尾,不然永远无法结束
  5. ==scanf函数的格式化字符串中还有别的字符串,必须要原样输入==
  6. scanf函数如果需要接受多个非字符类型的数据,可以通过空格,TAB,回车作为分隔符
  7. 清空输入缓冲区:
  • 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.格式:
  1. sizeof(变量/常量/数据类型);
int res = sizeof(3.14);
int res = sizeof(double);

int res = 10;
int res = sizeof(res);
//数据类型不能省略圆括号
  1. sizeof 变量/常量;
2.作用:

用于计算变量/常量/数据类型占用的存储空间

(5)逗号运算符

  1. 用于简化代码
  2. 有运算结果
  3. 结果是最后一个表达式的值.例:
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
  • ?:不能分开使用
  • 三目运算符优先级低于算数运算符

注意点:

  1. 在+ - * /的运算中,整数和整数的运算结果一定是整数.整数和小数的运算结果一定是小数
  2. 在%中不能出现小数
  3. 在%中被除数为0,结果就为0
  4. 在%中,结果的正负性,取决于被除数
  5. 自动类型转换不会改变原有量的值
  6. 自增自减只能用与变量
  7. 自增自减最好单独出现.例如:
int num = 10;
int res = 10 + num;
num++;
  1. 同一个表达式同一个变量同时自增自减,没有规定怎么运算,不同编译器结果不一样
  2. sizeof优先级高于算数运算符
  3. 关系运算符是左结合性(无法判断某个值是否在某个区间内).例:
int res = 10 > 5 > 3;//res = 0
  1. <= < > >= 优先级高于 == !== ==先优先级后结合性==.例:
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;
}
  1. case穿透问题
  • switch中只要有一个被匹配了,其它的case和default就会失效.(break的作用就是结束当前的switch语句)
  • default==写在最后==,default后的break可以省略
  1. default书写位置可以随便写(尽量写在最后)
  2. switch后()里只能放表达式/变量/常量,并且是整型或能被提升为整型.例:
switch(num) 
switch(2) 
switch(1 + 1) 
switch(1.1) //报错,小数不能被提升为整型
switch('a') //char本质为int类型
  1. switch的case后面只能放常量/表达式,并且是整型或能被提升为整型.例:
case num //报错
  1. switch的case的值不能重复
switch(2){
    case 1:
    
    case 1://会报错
}
  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(初始化表达式;条件表达式;循环后增量表达式){
    被控制的语句;
}
  1. 初始化表达式在循环执行过程中只会执行一次

(4)跳转语句

1.break
  1. 只能用在switch和循环结构中, 离开应用的范围没有任何意义
  2. 作用是跳出循环语句 while , dowhile,,for,switch
  3. 如果循环嵌套的时候,break只会跳出所在(最近的)的循环
  4. 不能离开应用范围,不然会报错.例:
if(1){
printf("随便写点东西\n");
break; 
// 离开应用范围后会报错
}
2.continue
  1. 只能用在循环中,离开应用范围没有任何意义
  2. 作用:跳过本次循环,进入下一次循环
  3. 不能离开应用范围,不然会报
  4. 如果循环嵌套的时候,continue只会跳出所在(最近的)的循环
3.goto
  1. 只能用于在同一个函数中跳转, 可以往前往后跳,只要是在同一个函数中
  2. goto需要配合标签使用(标签可以是任意的名称后面加上:).例:
printf("第一行代码\n");
goto lnj; 
printf("第二行代码\n");
lnj: printf("第三行代码\n"); //直接执行
  1. 一般不使用

注意点

  1. if结构中只有一个{}中的语句会被执行
  2. if省略大括号后只有紧随其后的那条语句才受控制(else只与最近的没有被匹配的if匹配)
  3. {}单独出现代表的是一个代码块.例;
int num = 10;
{
    int num = 18;
    printf("%i\n",num);//18
}
printf("%i\n",num);// 10
  1. 如果if/while省略了{},那么后面不能再定义变量(作用域混乱)
int num = 18;
if(num >= 18)
    int num = 666;
    printf("开网卡");
//看起来num的作用域是从定义的一行到return或}为止.但实际上num只有在if条件满足时才会执行,两者冲突.
  1. 任何值都有真假性
  2. 企业开发中一定不要用==来判断两个小数是否相等,可能会出现精度问题(建议使用 >= <=)
  3. 排序问题:两两比较后,最值会出现在最后
  4. 企业开发中能用if用if
  5. while省略大括号后只有紧随其后的那条语句才受控制
  6. while/if,任何值都有真假性,都可以嵌套其它合法代码
  7. 用于控制while的变量在循环的内部外部都可以使用.控制for的变量只能在循环内使用(企业开发中,能用for就用for)
  8. for和while都可以省略大括号.(省略后只能控制紧随其后的语句,且不能定义变量)
  9. 在企业开发中一般情况下,循环嵌套不会超过两层, 最多不超过三层
  10. 规律:循环嵌套的时候,外循环控制行数, 内循环控制列数
  11. 在企业开发中,但凡遇到需要解决很多行很多列的问题, 就要想到循环嵌套

六、函数

  • 优点:提高了代码的复用性,有利于维护
  • 作用:将某些代码封装起来
  • 格式:
返回值类型 函数名称(形参列表){
被封装到函数中的代码;
}

(1)如何定义函数

  1. 确定形参列表(告诉调用者调用时是否需要传递一些辅助的数据)
  2. 确定返回值和返回值类型(返回的数据是什么类型, 返回值类型就写什么类型)
  3. 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");
}
  1. 函数的声明可以声明多次,但函数只实现一次
  2. 返回值是int类型,可以不用编写函数声明(了解)
  3. 函数声明必须写在调用之前

(3)main函数

  1. main函数是系统自动调用的函数,不能手动调用
  2. 系统调用main函数时,默认会传递两个参数:
int main (int argc,const char *argv[]){
    
}
//argc:第二个数组保存数据的个数
//argv:默认保存了一个数据:当前文件的地址.并且可以动态的添加数据
//默认情况下,调用main函数时,回给argv这个数组中存放一个元素
  1. 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;
    }
}
  • 企业开发中,一般情况下,不会使用递归.在面试或文件操作(遍历目录)中出现较多

注意点:

  1. 函数可以有参数,也可以没有参数.函数的参数可以是零个或多个.
int sum(int a, int b){
    return a + b;
}
  1. 函数可以有返回值,也可以没有返回值(如果函数没有返回值, 那么返回值类型写void).例:
void test(){
    printf("test\n");
}
  1. (即使返回值类型,形参列表不同)函数的==名称也不能相同==
  2. 函数不能嵌套定义
  3. 如果是==基本类型的数据==(int,char,float,double)作为函数的参数,那么在函数内修改形参,不会影响外面实参的值
  4. 在函数内部不能定义和形参同名的变量

七、进制和位运算

(1)进制

  • 一种计数的方式
  1. 如果用16进制,前面加上0x(%x 输出)
  2. 如果用8进制,前面加上0(%0 输出)
  3. 如果用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的形式存储的
  • 数据在计算机内部是以补码的形式储存的, 所有数据的运算都是以补码进行的
  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
  1. 负数的原码、反码和补码:
    • 二进制的最高位我们称之为符号位,最高位是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(" ");
    }
}

注意点:

  1. 变量的内存是连续的
  2. 内存地址从大到小(只要定义变量,就会开辟内存空间)
  3. 计算机会从内存地址大的开始分配内存(内存寻址从大到小)也就是说先定义的变量内存地址大于后定义的变量
  4. 由于内存寻址是从大到小,所以存储补码也是从大到小(也就是从高位开始存储)
//高位         -->           低位
00000000 00000000 00000000 00001001
  1. ==变量的地址是所占用内存空间最小的那个地址==

类型说明符

  • 一般用于修饰int类型的
  1. 说明长度的:
short int//2个字节
long//32位编译器中4个字节,64位8个字节
long long//8个字节
  • 注意点:
    1. 如果存储的数据超出了类型对应的取值范围,那么就会导致存储的数据不对
    2. 由于内存非常有限,所以在编写程序的时候, 尽量合理的定义变量
    3. 由于说明长度的类型说明符一般都是用于说明int类型的,所以在使用的时候可以省略int:
short num1 = 123; // short == short int
long num2 = 123; // long  == long int
  1. 说明符号位的
  • unsigned 无符号的:
  • 注意点:
    1. 不把二进制的第一位当做符号位来使用,所以只能存储零和正数,不能存储负数
    2. 如果变量被unsigned修饰了,那么取出的时候必须使用%u,%u就代表用无符号的方式取出
    3. 应用场景:存储银行存款,学生的分数等不能出现负数的情况
  • signed 有符号的:
    • 默认int就是有符号的,就可以保存负数,零,正数,所以signed一般用不上

注意点:

  1. c语言的rand函数是一个伪随机数.(生成随机数)例:
//先导入:#include();
srand(time(NULL));//种一个种子
int res = rand();
  1. 三目是一个运算符,所以必须有结果(结果A和结果B的位置放的必须是变量,常量, 表达式)(如果放的是一个函数, 那么这个函数必须有返回值)
  2. 企业开发中,尽量不要写数字
  3. %p是专门用于输出变量地址的
  4. &是专门用于取出变量地址
  5. C语言的规则:不看怎么存只看怎么取
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容