C语言入门1

1 C转义字符

1.1 C常用的的转义字符

代码:

#include <stdio.h>

int main()
{
    // 1) \t: 一个制表位,实现对齐的功能
    // 2) \n: 换行符
    // 3) \\: 一个 \ 表示转义,第二个 \ 表示输出内容
    // 4) \": 一个 " 表示转义,第二个 " 表示输出内容
    // 5) \': 一个 ' 表示转义,第二个 ' 表示输出内容
    // 6) \r: 一个回车 
    printf("北京\t天津\t上海\n");

    printf("张三说:你好\n");

    printf("hello, \\world\n");

    printf("hello, \"world\n");

    printf("hello, \'world\n");

    // 分析:
    // 1. 先输出:小明小黄你好
    // 2. 然后输出:欧阳马匹你好
    printf("小明小黄你好\r欧阳马匹\n");

    return 0;
}

 运行结果:

2 变量

变量是程序的基本组成单位。

2.1 变量的介绍

2.1.1 变量的概念

变量相当于内存中一个数据存储空间的表示,可看作是一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量可以访问到变量的值。

2.1.2 变量的使用

// 声明变量
int num;

//变量赋值
num = 1;

//变量的使用
printf("num = %d\n", num);

//直接一步到位
int num_1 = 2;
printf("num_1 = %d\n" num_1);
#include <stdio.h>

int main()
{
    int num = 1; //整数
    double score = 98.5; //小数
    char gender = 'M'; //字符
    char name[] = "study c program"; //字符串
    // 说明
    /*整数输出 %d
      小数输出 %f 保留多少位小数输出%.2f
      字符输出 %c
      字符串输出 %s
    */
    printf("num = %d, score = %.2f, gender = %c, name = %s\n", num, score, gender, name);
    // num = 1, score = 98.50, gender = M, name = study c program
    return 0;
}

2.2 变量使用注意事项

1. 变量表示内存中的一个存储区域(不同的数据类型,占用的空间大小不一样);

2. 该区域有自己的名称和类型;

3. 变量必须先声明,后使用

4. 该区域的数据可以在同一类型范围内不断变化;

5. 变量在同一个作用域内不能重名;

6. 变量三要素:变量名、值、数据类型。

 2.3 变量的数据类型

2.3.1 数据类型一览图

 2.3.2 数据类型的小结

注意:

        1)在c中,没有字符串数据类型,使用的字符数组表示字符串;

        2)在不同系统中,部分数据类型字节长度不一样,int有2或者4。

2.4 各种数据类型的存储大小

各种数据类型的存储大小与操作系统、系统位数和编译器有关。

c语言规定:short占用的存储空间不能多于int,long占用的存储空间不能少于int。

win64中各类型的存储大小:

#include <stdio.h>

int main()
{
    printf("sizeof(char) = %d\n", sizeof(char)); //1
    printf("sizeof(short) = %d\n", sizeof(short)); // 2
    printf("sizeof(int) = %d\n", sizeof(int)); // 4
    printf("sizeof(long) = %d\n", sizeof(long));// 4
    printf("sizeof(long int) = %d\n", sizeof(long int)); //4
    printf("sizeof(long long int) = %d\n", sizeof(long long int)); // 8
    printf("sizeof(float) = %d\n", sizeof(float)); // 4
    printf("sizeof(double) = %d\n", sizeof(double)); // 8
    printf("sizeof(long double) = %d\n", sizeof(long double)); // 16 
    printf("sizeof(long long) = %d\n", sizeof(long long)); // 8
    return 0;
}

linux64中各类型的存储大小:

#include <stdio.h>

int main()
{
    printf("sizeof(char) = %d\n", sizeof(char)); //1
    printf("sizeof(short) = %d\n", sizeof(short)); // 2
    printf("sizeof(int) = %d\n", sizeof(int)); // 4
    printf("sizeof(long) = %d\n", sizeof(long));// 8
    printf("sizeof(long int) = %d\n", sizeof(long int)); //8
    printf("sizeof(long long int) = %d\n", sizeof(long long int)); // 8
    printf("sizeof(float) = %d\n", sizeof(float)); // 4
    printf("sizeof(double) = %d\n", sizeof(double)); // 8
    printf("sizeof(long double) = %d\n", sizeof(long double)); // 16 
    printf("sizeof(long long) = %d\n", sizeof(long long)); // 8
    return 0;
}

 2.5 整数类型

整数类型里面包含:整型(int)、短整型(short int)、长整型(long int)。

2.5.1 无符号类型unsigned

编译器默认在我们声明变量时,就缺省加上了signed这个关键字。当我们的变量需要变成无符号时,需要用到unsigned进行修饰。

无符号类型(unsigened)只能搭配char、int、short int、long int一起使用,用unsigned修饰后的数字,就是不带负号的数字,无法存放负数。

注:不能定义unsigned float和unsigned double类型,否则会报错

此表基于win64:

数据类型 名称字节值范围
short短整型2-32,768 ~ 32,767
int整型4-2,147,483,648 ~ 2,147,483,647
long长整型4-2,147,483,648 ~ 2,147,483,647
unsigned short无符号短整型20 ~ 65535
unsigned int无符号整型40 ~ 4,294,967,295
unsigned long无符号长整型40 ~ 4,294,967,295

2.6 浮点类型

浮点型分为单精度浮点型(float)双精度浮点型(double)

两者的都可以用来存放小数,区别在于双精度浮点型可以精确的小数位比单精度浮点型的多。

数据类型名称字节范围值
float单精度浮点型41.2E-38 ~ 3.4E+38(精确到小数点后6位)
double双精度浮点型82.3E-308 ~ 1.7E+308(精确到小数点后15位)

说明一下: 

1)关于浮点数在机器上中的存放形式的简单说明,浮点数 = 符号位 + 指数位 + 位数位,浮点数是近似值;

2)尾数部分可能丢失,造成精度损失。

2.6.1 浮点数使用细节

1)浮点型常量默认为double型,声明float型常量时,必须加上’f‘或'F';

2)浮点型常量有两种表示形式:

        十进制数形式,如:5.12、512.0f、.512

        科学计数法形式,如:5.12e2、5.12E-2

3)通常情况下,应该使用double类型,因为它比float类型更精准;

4)printf("d = %f\n", d); 在输出时,默认保留小数点6位。

#include <stdio.h>

int main()
{
    // 浮点数默认为double类型,声明float类型时,须在后面加'f'或'F'
    float f = 1.2; // 从double到float截断,1.2是double类型
    float f_1 = 1.2f;
    double d1 = 1.2;

    double d2 = 5.12;
    double d3 = .512; // 等价于0.512

    double d4 = 5.12e2; // 等价于5.12 * (10^2) = 512
    double d5 = 5.12e-2; // 等价于5.12 * (10^-2) = 0.0512
    // f = 1.200000 f_1 = 1.200000 d1 = 1.200000 d2 = 5.120000 d3 = 0.512000 d4 = 512.000000 d5 = 0.051200
    printf("f = %f f_1 = %f d1 = %f d2 = %f d3 = %f d4 = %f d5 = %f\n", f, f_1, d1, d2, d3, d4, d5);
    double d8 = 1.19823294;
    printf("d8 = %f\n", d8); // d8 = 1.198233
    return 0;
}

2.7 字符类型

字符类型可以表示单个字符,字符类型是char,char是一个字节(可以是字母或者数字),多个字符称为字符串,在C语言中,使用char数组表示,数组不是基本的数据类型,而是构造类型。

数据类型名称字节范围值
char字符类型1-128 ~ 127
unsigned char无符号字符类型10 ~ 255

2.7.1 字符类型使用细节

1)字符常量使用单引号('')括起来的单个字符。例如:char c1 = 'a',char c2 = '9';

2)C语言中还允许使用转义字符'\'来将其后的字符转为特殊字符常量。例如:char c3 = '\n'; (表示换行符);

3)在C语言中,char的本质是一个整数,在输出时,是ASCII码对应的字符;

4)可以直接给char附一个整数,在输出时,会按照对应的ASCII字符输出;

5)char类型时可以进行运算的,相当于一个整数,因为它都对应有Unicode码。

 2.7.2 字符类型本质

1) 字符类型存储到计算机中,需要将字符对应的码值(整数)找出来:
        存储:字符'a' --> 码值(97) --> 二进制(110001) --> 存储

        读取:二进制(1100001) --> 码值(97) --> 字符'a' --> 读取

2)字符和码值的对应关系是通过字符编码表决定的(是规定好)

2.8 基本数据类型转换

2.8.1 自动类型转换

在C语言中,在进行赋值或者运算时,精度小的类型自动转换精度大的数据类型,这个就是自动类型转换。

数据类型按精度大小排序为:

 数据类型自动转换表:

 2.8.2 自动类型转换细节说明

1)有多种类型的数据混合运算时,系统首先自动将所有数据类型转换成精度最大的那种数据类型,然后再进行计算(如int型和short型运算时,先把short转成int型后再进行运算);

2)若两种类型的字节数不同,转换成字节数大的类型,若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型;

3)在赋值运算中,赋值号两边的数据类型不同时,赋值号右边量的类型将转换为左边量的类型,如果右边变量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入进行舍入(只针对小数部分)。

#include <stdio.h>

int main()
{
    int a = 1.98;
    float f1 = 1.23f;
    double d1 = 2.67232876;
    f1 = d1;
    a = d1;
    printf("a = %d\n", a); // a = 2
    printf("f1 = %f\n", f1); // f1 = 2.672329

    return 0;
}

2.8.3 强制类型转换

精度高的数据转换为精度小的数据类型。使用时要加上强制转换符(),但可能造成精度降低或溢出,格外要注意。

强制类型转换一般格式如下:

        (类型名)表达式;

这种强制类型转换并不改变操作数本身。

2.8.4 强制转换的细节说明

1)当进行数据从 精度高 --> 精度低,就需要使用到强制转换;

2)强制转换只针对于最近的操作数有效,往往会使用小括号提升优先级。

#include <stdio.h>

int main()
{
    double d = 1.982;
    int num = (int)d; //这里注意,不是四舍五入,而是直接截断小数后部分

    printf("num = %d, d = %f\n", num, d); // num = 1, d = 1.982000

    // 强制转换只对最近的数有效,如果希望针对更多的表达式转换,使用()
    int num1 = (int)3.5 * 10 + 6 * 1.5;  // 想要这样35 + 9 = 44,但实际30 + 9 = 39
    int num2 = (int)(3.5 * 10 + 6 * 1.5);
    printf("num1 = %d, num2 = %d\n", num1, num2); // num1 = 39 num2 = 44
    return 0;
}

 2.8.5 案例总结

#include <stdio.h>

int main()
{
    char c ='a';
    int i = 5;
    float f = .345f;
    double d = 1.34;

    double result = c + i + f; // float -> double 自动类型转换
    char result1 = c + i + d; // 会有一个警告 double -> char 会有精度丢失
    return 0;
}

3 指针入门

3.1 指针基本介绍

指针表示一个地址(存放的是地址)。

代码演示:

#include <stdio.h>
int main()
{
    int num = 1;

    // 定义一个指针变量
    // 说明
    // 1. int* 表示类型为指针类型
    // 2. 名称ptr,ptr就是一个int* 类型
    // 3. ptr指向了一个int类型的变量地址
    int *ptr = &num;

    // 输出一个变量的地址,使用格式是%p
    // &num表示取出num这个变量对应的地址
    printf("num = %d, &num = %p\n", num, &num); // num = 1, &num = 000000000061FE14

    // *ptr 表示获取指针指向的值
    // ptr 表示存放的地址
    printf("*ptr = %d, ptr = %p\n", *ptr, ptr); // *ptr = 1, ptr = 000000000061FE14
    
    // 指针变量,本身也有地址
    printf("ptr的地址 = %p\n", &ptr); // ptr的地址 = 000000000061FE10
    return 0;
}

 内存演示:

3.2 指针细节 

基本类型,都有对应的指针类型,形式为 数据类型* ,比如int对应的指针就是int*,float对应的指针类型就是float*,以此类推。

3.3 值传递和地址传递

3.3.1 值传递

定义:将变量指向的存储内容,在传递/赋值时,拷贝一份接收变量。

默认值传递的类型:基本数据类型(整数类型,小数类型,字符类型),结构体,共用体。

3.3.2 地址传递

定义:如果是指针,就将指针变量存储的地址,传递给接收变量,如果是数组,就将数组的首地址传递给接收变量。

默认传递地址的类型:指针,数组。

4 常量

4.1 基本介绍

1)常量是固定值,在程序执行期间不能改变。这些固定的值,又叫做字面量

2)常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量、字符串常量和枚举常量。

3)常量的值在定义后不能改变。

 4.2 经常使用的常量

4.2.1 整数常量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。

12   // 十进制
0123 // 八进制
0x5a // 十六进制
87   // 整数
97u  // 无符号长整数
98l  // 长整数
98ul // 无符号长整数

 4.2.2 浮点常量

浮点常量由整数部分、小数点、小数部分和指数部分组成。可以使用小数形式或者指数形式来表示浮点常量。

3.1929393   // double常量
3.141592e-7 // 科学计数法
2.4f        // float常量

 4.2.3 字符常量

字符常量是括在单引号中(''),字符常量可以是一个普通的字符(例如 'a'),一个转义字符(例如 '\n')。

'2'
'd'
'\n'
'\r'

 4.2.4 字符串常量

字符串常量是括在双引号("")中的,一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。

#include <stdio.h>

int main()
{
    char str1[20] = "hello world";
    char str2[100] = "hello \
    animal";

    printf("str1 = %s str2 = %s\n", str1, str2);
    return 0;
}

4.3 常量的定义 

定义常量的两种方式:

1)使用 #define 预处理器。

2)使用const关键字。

4.3.1 #define 预处理器

1)#define 预处理器定义常量的形式

#define 常量名 常量值

2) 代码演示

#include <stdio.h>

#define PI 3.14

int main()
{
    // PI = 3.14159 这样是不可以的,因为PI是常量
    double area;
    double r = 1.2;
    area = PI * r *r;
    printf("area = %.4f\n", area);  // area = 4.5216
    return 0;
}

4.3.2 const 关键字

1)可以使用const声明指定类型的常量。

const 数据类型 常量名 = 常量值;

 2)案例演示

#include <stdio.h>

// 说明
// 1. const是一个关键字,规定好,表示后面定义了一个常量
// 2. PI是常量名,即使一个常量,常量值就是3.14
// 3. PI因为是常量,因此不可以改变
// 4. const定义常量时,需要加分号
const double PI = 3.14;
int main()
{
    // PI
    double area;
    double r = 1.2;
    area = PI * r * r;
    printf("area = %.4f\n", area); // area = 4.5216
    return 0;
}

4.3.3 const和#define的区别

1)const定义常量时,带类型,#define不带类型;

2)const是在编译、运行的时候起作用,而#define是在编译的与处理阶段起作用;

3)#define只是简单的替换,没有类型检查。简单的字符串替换会导致边界效应;

4)const常量可以进行调试,#define是不能进行调试的,主要是预处理阶段就已经替换掉了,调试的时候就没它了;

5)const不能重定义,不可以定义两个一样的,而#define通过#undef取消某个符号的定义,再重新定义;

6)#define可以配合#ifdef、#ifndef、#endif来使用,可以让代码更加灵活,比如我们可以通过#define来启动或者关闭调试信息。

针对3、5两点的代码分析: 

#include <stdio.h>

#define A 2
#define B (A + 1)
#define C A / B * 4
double b = 2 / 3 * 4;

// const不能重复定义,不可以定义两个一样的,而define通过undef取消某个符号的定义,在重新定义
const double PI = 3.14;
// const double PI = 3.14;

#define R 23
#undef R
#define R 14

int main()
{   
    // C = A / A + 1 * 4 = 2 / 2 + 1 * 4 = 5
    // C = A / (A + 1) * 4 = 2 / (2 + 1) * 4 = 2 / 3 * 4 =  0
    printf("C = %d\n", C); // C = 0
    printf("b = %f\n", b); // b = 0.000000
    return 0;
}

 针对第6点的代码分析:

#include <stdio.h>

#define DEBUG
int main()
{
#ifdef DEBUG
    printf("ok\n");
#endif

#ifndef DEBUG
    printf("no ok\n");
#endif
    return 0;
}

进阶使用:

/* TEST1 或 TEST2被定义,则选择执行printf1,否则执行printf2 */
#if defined TEST1 || defined TEST2
	printf1(".....");
#else
	printf2(".....");
#endif

/* TEST1 或 TEST2未被定义,则选择执行printf1,否则执行printf2 */
#if !defined TEST1 || !defined TEST2
	printf1(".....");
#else
	printf2(".....");
#endif

 笔记整理,来自大佬视频!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值