【C语言篇】☞ 2. 常量、变量、scanf函数和printf 函数

常量

C语言有丰富的数据类型,在开发中,一般用常量或者变量来表示这些数据

""表示数据。常量,则表示一些固定的数据,也就是不能改变的数据。

10.1;// 双精度double

5.2f; //单精度float

'a'; // 字符型常量

'ab'; // 错误

''; // 错误写法, 因为一个汉字占3个字节

'\n';//字符型常量(转义字符,表示单个字符)

  

定义常量的方法:

const int a=100;

变量

变量:代表了内存的一个空间,用来存放经常变化的数据。(变量名就是空间的名称,变量的类型决定着变量占用多大的内存空间)

变量名:是我们操作数据(存放数据)的依据。

初始化:就是清空(赋初值,0/NULL)的意思,清理一些垃圾数据。

变量的使用:存值和取值。

  int a; //定义一个变量,未初始化。

  a的值的可能性:1) 系统的数据; 2) 上一个程序遗留的数据; 3) 垃圾数。

变量的作用域:(变量的使用范围)

局部变量(内部变量):在函数的内部或者代码块的内部定义的变量。

  ※ 作用域:从局部变量定义的位置开始,到它所在的代码块或函数体的“}”为止。

  ※ 注意:在代码块的内部可以定义和块外部同名的变量,块内部的会暂时屏蔽(外部的不起作用)块外部的变量的作用域。  

#include <stdio.h>

 

int main() {

    int age=20;

    //代码块代表一个空间,与age的空间并列

    {//代码块开始

        int a=5;

        printf("a=%d\n", a); //a=5

        int age=25; //在代码块内部可以定义和代码块外部同名的变量

        printf("age=%d\n",age); //age=25;

    }//代码块结束(此时代码块内部所有的空间会释放)

    printf("age=%d\n", age);//age=20;

    return 0;

}

变量的命名:命名需要符合标识符语法要求。

  • 必须以字母或下划线开头
  • 包含字母、下划线或数字
  • 大小写敏感的
  • 不能与关键字冲突
  • 标识符理论上讲,长度无限制,但太长了会被编译器截断

变量的声明(定义):在相同的作用域内变量不可重复定义!

语法格式:变量类型  变量名;

  如: int age;

    float result;

    double x,y,z;

  变量类型:表示我所定义的这个变量可以存放什么样类型的常量

  变量名称:它一个标示符,来标识我们在内存中开辟这块存储区域,方便我们以后使用

  变量的作用域:从定义那一行开始直到其所在大括号结束为止

//1.定义变量(即在内存中开辟一块空间,空间的大小跟定义的类型有关,空间的名字就是变量名)

int age//这一行代码就在内存中开辟一块4个字节的存储区域,它名字叫age;这块存储区域是用来存放int类型的数据的

//2.初始化:变量第一次赋值称为初始化。

age=22; //这行代码是把22,放到名字为age的这块存储区域中

   

  • 未经声明的变量不能使用;变量在使用之前要声明,且只声明一次。
  • 变量用来保存程序执行过程产生的临时值,可以多次赋值,但只会保存最后一次的值。

 

变量的存储

  • 变量所占的存储空间(字节数):跟变量的类型和编译器环境有关。
  • 变量存储单元的第一个字节的地址就是该变量的地址(详细地址/首地址)
  • 任何变量在内存中都是以二进制的形式存储:

   一个负数的二进制形式,其实就是对它的正数的二进制形式进行取反再加1

1. 不同的数据类型占用不同的存储空间:

  

2. 不同数据类型表示的范围:

  

  

变量在内存中怎么储存?(变量为什么要有类型)

  • 只要定义变量,系统就会开辟一块存储空间给我们的变量存储数据
  • 越先定义的变量,内存地址越大(从字节地址最大的开始找)
  • 内存寻址是从大到小,高位放在高字节上,低位放在低字节上
  • 变量的地址就是变量所占的存储空间最小的字节地址(即首地址:&变量名称)

  计算机中最小储存单元是字节,每个字节都有一个地址。

    

// 扩展:获取每个字节中存储的数据

    char *p = &value;

    for (int i = 0; i < sizeof(value); i++) {

        printf("%i\n", *(p + i));// 取出每个字节中存储的数据(88 2 0 0)

    }

注意:在这里,地址(int型指针)+1 相当于 char型指针+4

  

//  当定义变量的时候,这个变量里面究竟有什么东西是不确定的

    int score;//垃圾值

 

//  printf函数打印 % 字符要用 %% 才能打印

printf("5%%2=%d\n",5%2);//结果为:5%2=1

 

 

交换整型变量ab的值:

  比如:a=10b=11;交换后:a=11b=10。用两种方式实现:

  1. 使用第三方变量

    int temp;

    temp = a;

    a = b;

    b = temp;

  1. 不使用第三方变量

    a = b - a;

    b = b - a;

    a = b + a;

printf 函数:

printf函数称为格式输出函数,其关键字最末一个字母f即为“格式”(format)之意

printf函数调用的一般形式为:(其中格式控制字符串用于指定输出格式)

  printf(“格式控制字符串”, 输出表列); 

格式字符串的一般形式为:(其中方括号[]中的项为可选项)

  %[标志][输出最小宽度][.精度][长度]类型。

//利用printf函数可以计算字符串的长度

int length = printf("iOS开发\n");

printf("共占%i个字节\n", length);// 10 (1+1+1+3+3+1)

1. 类型(格式控制符)

  

 2. 标志

  标志字符为 -、+、# 和空格四种,其意义下表所示:

  

  • 指定位宽:
    1. %0nd:在%与d之间,0n,n表示输出的数字的宽度,如果不够就用0补齐左边(重点)
    2. %nd:在%与d之间n,n表示输出的数字的宽度,如果不够就用空格补齐左边
    3. %-nd:在%与d之间 -n,n表示输出的数字的宽度,如果不够就用空格补齐右边
  • 指定位数:

      %m.nf:在%与f之间,可以有m.n,m表示输出数字所占的宽度,m表示小数点后面的位数,如果不够会用空格补齐左边

#include <stdio.h>

 

int main() {

    float m=3.141592f;

    printf("m=%8.4f\n", m);//默认空格补在左边

//  %-m.nf 输出共占m位,其中小数占n位,如果数值宽小于m右端补空格

    printf("m=%-8.4f\n", m);//-号表示空格补右边

//  %*.*特殊用法:

    printf("m=%*.*f\n",6,2,m);//m=  3.14

    printf("%.*s\n",4,"abcdkkkkkkk");//abcd

    return 0;

}

%g:自动选f格式或e格式中较短的一种输出,且不输出无意义的零。

%p:输出地址(指针)

/**

 *  %f默认会保留6位小数

 *  指定保留多少位小数: %.nf, 其中n就是需要保留多少位小数, f用于输出实型

 */

float value = 3.14;

printf("%f\n", value);//3.140000

printf("%.2f\n", value);//3.14

 

/**

     *  floatdouble的有效位数:

     *  float最多表示7位有效数据。double最多表示16位有效数据。

     *

     *  float类型要点:

     *  1.小数末尾要加f/F,指定为float类型

     *  2.默认情况保留6位小数

     *  3.精度为7位有效数字(左边第一个不为零的数开始,除小数点外7位数字有效,超出7位的是垃圾数据)

     *

         1bit(符号位) 8bits(指数位) 23bits(尾数位)

         精度是由尾数的位数来决定的

         float2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,

         但绝对能保证的为6位,也即float的精度为6~7位有效数字;

     */

    float value = 3.1415926525;

    printf("%f\n", value);//3.141593 (默认情况保留6)

    //float有效数字是7位,多余位数则会显示垃圾数据(不准确)

    printf("%.10f\n", value); //3.1415927410

 

    // 如何想完整的输出那么必须将数据保存double类型, 因为double类型的有效位是15

    double value = 3.1415926525;

    printf("%.10lf\n", value);

    

    //如何提高逼格(保留几位小数不确定时)

    //指定保留多少位小数时,可以通过*号占位,以后赋值具体保留的小数位

    float value = 3.1415926;

    printf("%.*f\n", 5, value);

    &C语言中的一个地址运算符,可以用来获取变量的地址

    &可以获取变量的地址,例如:&num

    *可以根据地址数据找到变量,例如:*(&num)

scanf 函数

  scanf函数是一个阻塞式函数

  程序会停在scanf函数出现的地方,直到接收到数据才会执行后面的代码

//  使用scanf接收用户从键盘上输入

    scanf("%d", &a);//注意: 必须告诉scanf函数变量的详细地址, 才能存储用户输入的数据

//  %d之间可以有数字n,这个n表示接受数据的宽度

    scanf("%2d",&a);

scanf 函数要点:

  1. 键盘输入的数据与格式化字符串中的要匹配, 不匹配时scanf函数就会自动终止。
  2. scanf接收多个数据时,为了防止出错一般加一个分隔符(例如:,

    (空格、回车、Tab可以做%c除外的分隔符,因为空格、回车、Tab是字符)

  1. 不能在scanf的格式化字符串末尾写上\n

    

    

// \n代表换行

// 如何告诉scanf函数我们输入完毕? 回车(\n)

// 因为回车是scanf的结束符, 所以不能在scanf的格式化字符串末尾写上\n。(如果加在末尾,会永远结束不了输入,即scanf函数不会终止)

// 如果不小心把\n放到了scanf格式化字符串的末尾,也可以破,原样输入(输 \n或输入一个不匹配的类型(如:输 a)

scanf("%i%i\n", &num1, &num2);

 

scanf函数实现原理

scanf函数的运行原理:

    系统会将用户输入的内容放入输入缓冲区

    scanf函数会从输入缓冲区中逐个取出内容赋值给格式符,如果类型不一致不会修改原有数据。

  

  

scanf录入数据的时候,录入格式必须与格式化字符串中格式一致

  1. scanf("%d-%d-%d", &a, &b, &c);

    注意:scanf占位符中间分割符可以是任意的,不一定要用中划线-,可以是逗号、空格、星号*、井号#等等,甚至是英文字母

  1. scanf("%d %d %d", &a, &b, &c);

    3%d之间是用空格隔开的,我们在每输入一个整数后必须输入一个分隔符,分隔符可以是空格、tab、回车

    scanf格式字符串最后面不要加\n,比如scanf("%d\n", &a);这将导致scanf函数无法结束。

   

面试题

  int  a;

  请问a里面有值吗,是多少? 垃圾值

//判断一个年份是否是闰年

    //能被4整除,但(并且)不能被100整除,或者能被400整除

    int year;//保存年份

    printf("请输入一个年份:");

    scanf("%d", &year);

    if((year%4==0 && year%100!=0) || year % 400 == 0){

        printf("是闰年\n");

    }else{

        printf("不是闰年");

    }

 

  ※ 变量分析题:(注意变量的作用域)

  

 

posted @ 2017-01-30 11:56  专注·精彩  阅读(1493)  评论(1编辑  收藏  举报