C语言基础——编译,分析,数据类型和进制

c 语言编译

编译型语言:通过编译器编译源代码文件生成机器能够识别可执行文件/二进制

编译器名字 gcc,arm-linux-gcc, arm-none-linux-gnueabi

可通过 gcc -v 查看编译器是否存在

缺省状态:编译器名字 源代码文件名字

eg:gcc hello

命令格式:

编译器名字 源代码文件名字 指定参数(-o) 生成的程序文件名字

eg:

gcc hello.c -o hello

gcc hello.c --会默认生成 Linux 可执行程序 a.out

在Windows中则是 a.exe

通过./a.out执行文件

make

可以通过构建工具(make),直接选择依赖条件/规则来编译

# 假设有 hello.c 文件,如果想要使用构建工具进行编译,安装构建工具

sudo apt install make

1. 编译(make 后面的参数是用来指定从当前查找以用户指定的这个名字前缀的c源代码文件) make hello

2.执行

# . 当前路径上找一个即将要执行的程序

# / 路径拼接符

./hello

.\hello.exe # 后缀不能少,因为Windows就是以后缀来区分文件类型

查看文件属性

file hello

hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=2500b0e3243b8052a5cdb06925e15447ea54c4ba, not stripped

x86-64---》该程序可以运行在 x86-64 平台

ubuntu linux ARM ---> 开发板

ELF ---》二进制文件格式

编译过程做什么事情

检查语法

编译之后的表现

1)编译通过

编译之后没有任何提示,说明 编译完美通过,生成一个可执行程序。

2)编译警告

编译之后会出现warning提示,还是可以生成一个可执行程序。比如头文件 没写

警告虽然不代表出错,有些警告可以忽略,但是有些警告不能忽略

3)编译出错

语法出错,会有一个明显的提示error,根据提示出错的信息找到问题所在

注意:

  1. 如果使用缺省参数进行编译,则要明确,运行时的程序是(Linux:a.out/Window:a.exe),但如果使用指定参数进行编译,则必须要明确的程序名字是-o参数后面程序文件名字

C 程序

#include <stdio.h>

int main(void)

{

printf("Hello, World!\n");

return 0;

}

这段代码是一个C语言程序。让我们一步步来了解它:

  • #include : 这是一个预处理指令,它告诉编译器在编译之前包含标准输入输出库的内容,这样我们就可以使用其中的printf函数。
  • int main(void): 这是主函数,所有的C程序都必须有且只有一个main函数作为程序的入口。返回类型int表示函数执行后返回一个整数值,void表示这个函数不接受任何参数。
  • printf("Hello, World!\n");: 这是一个库函数printf的调用,它的作用是向屏幕输出一段文字。"%s"表示输出字符串,\n表示换行符。
  • return 0;: 这是main函数的返回语句,它表示程序正常结束,并返回给操作系统一个整数值0,通常表示程序成功执行。

头文件

#include <stdio.h>

  1. C语言程序中,任何符号(包括变量和函数)的使用,都是需要提前声明的。
  2. 如果程序用到了系统库函数,那么就需要包含相应的系统头文件来进行声明。
  3. 上述代码中用到了库函数 printf ,而这个函数的声明在头文件 stdio.h 中,因此在该程序中需要包含此头文件。

声明

概念:对源文件外定义的某个符号进行描述的过程,称为声明

作用:经过声明的符号,编译器才能正确识别和编译,否则编译器不认识,无法判定语法错误

符号:变量、函数等

示例:

// 声明一个变量符号number

int number = 100;

// 声明一个函数符号function

void function(int size, char *buf);

主函数

  1. 主函数是必须有的,每一个C语言程序有且仅有一个main函数,哪怕是空的。
  2. 主函数的名字是固定的,叫 main ,这个函数名不可被挪作他用。
  3. 主函数是程序的入口,也就是程序开始运行的地方。
  4. 主函数分解如下:

// int: 返回值类型,代表主函数最终的执行结果是一个整型数据

// main(void): main是函数名,这个名字不能变

// void是函数参数列表,可以省略 int main(void) { }

在 Linux 环境下,主函数 main 根据程序最终是否需要接收外部命令行参数,实际上有两个版本:

// 不接收外部命令行参数的版本 int main() { ... }

// 接收外部命令行参数的版本 int main(int argc, char **argv) { ... }

printf函数

它的功能就是:向终端输出一段指定格式的数据。

// 向终端输出一段字符串

printf("Hello World!\n");

格式输出控制符

  • 概念:函数 printf被称为格式化IO函数, 因为它是按照指定格式来操作数据的。以常见的整数、浮点数和字符串为例,printf 函数相关的控制格式符如下所示:

// 格式化输出函数 printf();

printf("格式化控制符", 数值);

// 根据需要输出不同格式的数据

printf("%d\n", 100); // 输出1个整数

printf("%d, %d\n", 100, 200); // 输出2个整数

printf("%f\n", 3.14); // 输出浮点数

printf("%c\n", 'x'); // 输出字符

printf("%s\n", "abcd"); // 输出字符串

printf("a=%d, %s\n", "abcd"); // 输出字符串

%u --->unsigned int

%hu half unsigned int

%hhu half half unsigned int

语法点:

  • 类似 %d、%f 被称为格式控制符
  • 一个格式控制符对应一个数据
  • ‘\n’ 是一个字符,表示回车符

格式控制符:

    1. 十进制整数:%d
    2. 八进制整数:%o
    3. 十六进制整数:%x
    4. 字符:%c
    5. 字符串:%s
    6. 单精度浮点数:%f
    7. 双精度浮点数:%lf
    8. 长双精度浮点数:%Lf
    9. 地址:%p

4.return语句

C语言中的关键字 return 的含义是结束一个函数,并返回某个数据(若有)。而具体到 main 函数中时,由于主函数 main 的结束同时也意味着整个程序的结束,因此在上述 Hello World 程序中 return 后整个程序就退出了

一般而言,程序正常退出时,main函数返回值是0;当程序异常退出时,main函数返回值是非0。

注意:main函数的返回值是给上一级进程的,因此理论上讲在当前的单进程程序中,main函数的返回值究竟是多少都无所谓,因为根本没有去使用这个返回值,除非在多进程程序中,进程间才需要使用main函数的返回值来传递信息。

数据类型

概述

很多时候,我们编写程序的目的是让计算机能够帮助我们去处理数据。

计算机要处理的数据(诸如数字、字符串、文字、符号、图形、音频、视频等)是以二进制的形式存放在内存中的。

而且在程序中数据是有类型区分,通常分为整型、浮点型、字符串等等。数据类型其实是固定大小内存的别名。并且描述了一个变量存放什么类型的数据

注意:数据类型不仅帮助我们组织和操作数据,还决定了程序如何有效地利用内存。

          了解数据类型的内存需求是理解计算机如何管理和操作数据的关键。

内存存储容量单位

字节(byte B):计算 存储容量的一种单位。

比特位(bit):二进制数 0 1

1个字节(byte) = 8位(bit) 二进制

1个千字节(KB) = 1024字节(byte)

1M = 1024KB

1G = 1024M

1T = 1024G

数据类型分类和计算方法

基础类型

        整数类型

                短整型 short / short int

                整型 int

                长整型 long / long int

        浮点类型

                单精度 float

                双精度 double

        字符类型 char

构造类型/自定义类型

        结构体(struct)

        联合体/共用体(union)

        枚举(enum)

指针类型 (*/&),存储地址

空类型 void

计算某个数据类型或者变量所占的字节数

---->        sizeof        ( 某个数据类型或者变量名)

整型

概念

表达整数类型的数据

语法

// type var_name = 值;

int a = 123;// 定义了一个专门用来存储整数的变量a

注意

  1. nt 的本意是 integer,即整数的意思
  2. int a 代表在内存中开辟一块小区域,称为 a,用来存放整数,a 一般被称为变量。
  3. 变量 a 所占内存大小,在不同的系统中是不一样的,64位系统典型的大小是4个字节。
  4. 变量 a 有固定的大小,因此也有取值范围,典型的范围是:-2147483648到2147483647(-2^32-1到2^32-1)

整型修饰符

short:用来缩短整型变量的尺寸,减少取值范围并节省内存,称为短整型

long:用来增长整型变量的尺寸,增大取值范围并占用更多内存,称为长整型

long long:用来增长整型变量的尺寸,增大取值范围并占用更多内存,称为长长整型

unsigned:用来去除整型变量的符号位,使得整型变量只能表达非负整数

注意:使用整型修饰符后,关键字 int 可以被省略

符号位

有符号的整型数据,首位为符号位,0表示正数,1表示负数。

无符号的整形数据,没有符号位。

数据类型的值域范围

溢出:超过数据所能表达的范围,称为溢出,就像汽车里程表,最大值和最小值是相邻的

unsigned char 0 ~ 255

signed char -128 ~+127

正数: +0 +1 ....+127

负数: -0 -1 ......-127

由于 +0 和 -0 重复了, -0 表示 -128

unsigned short 0~65535(2^16-1)

unsigned int 0 ~ 4294967295(2^32-1)

eg:

(1)

        unsigned char a = 255; // 0 - 255

        char b = 255; // -128 ~ +127

        printf("%d %u\n",a,a); // 255 255

        printf("%d %u\n",b,b); // -1 4294967295

(2)        

        unsigned short a = -1; // 0-65535

        int b = a; //65535

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

        printf("%d\n",b);// 65535

(3)

        unsigned char a = -1; //0-255 a--->255

        unsigned int b = -1; // 0- 4294967295

        printf("%d %u\n",a,b); //a == 255 b == 4294967295

总结:

(1)当编译器以整型输出时(%d),是以补码还原的方式来解读的。

(2)当CPU对数据进行运算时,直接以内存中存放的形式进行运算,即补码的形式

(3) %u 打印的时候, 值域的范围: unsigned int 0-4294967295

(4) %hhu 打印的时候, 值域的范围: unsigned char 0-255

注意:

        printf("true size:%d\n",sizeof(true));  占 4个字节         

        printf("false size:%d\n",sizeof(false));  占 4个字节

        printf("false size:%d\n",sizeof(bool)); 1

总结:

1)数据类型在内存中所占的字节数跟C语言的编译系统有关

2)计算 某个数据类型 所占的字节数可以用sizeof

3)  布尔类型 要添加 #include<stdbool.h>

编码形式

计算机内部使用二进制补码来表示带符号整数。补码是为了简化计算机对整数加减法的实现而设计的一种表示方法。

原码:正数直接使用二进制来表达,最为直观的表示法,将十进制的数值转换成二进制的数值,比如a=100,在内存中是 00…001100100

反码:针对于负数的操作,原码取反(除符号位,0变成1,1变成0)

补码:负数用绝对值取反加一来表达,比如a=-3,在内存中是11…1111111101 注意负数的补码在取反加一的时候,符号位是不动的

正整数,原码,补码,反码,都是一样

char 类型

单引号只能存一个字符,即便加入多个字符,但是编译器只会存储第一个

ascii 码

概念:char数据实际上是在内存存放的是一个小于255的编号(无符号整数)用来表示字符,这个编号叫做 ASCII 码。

如何查看 ascii 码??

man ascii

注意:如果是 sizeof('a') ,那么结果就是4 ,因为在使用sizeof运算的时候,字符数据 就会转换为ascii码的形式,所以不能使用这种方法计算单个字符的大小

转义字符

概念:

所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。

而C中定义了一些字母前加 '\' 来表示常见的那些不能显示的ASCII字符,如'\0','\t','\n'等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符的意思了。

它告诉编译器需要用特殊的方式进行处理。

浮点型

概念:用来表达实数(小数)的数据类型

分类:

  • 单精度浮点型(float),在64位系统中典型尺寸是4字节,精确到小数点后6位 %f
  • 双精度浮点型(double),在64位系统中典型尺寸是8字节,精确到小数点后15~16位 %lf
  • 长双精度浮点型(long double),典型尺寸是16字节

占用内存越多,能表达的精度越高

float f1; // 单精度

double f2; // 双精度

long double f3; // 长双精度

科学计数法:

C语言中一般浮点数有两种表示形式: 十进制形式  +  指数形式 ,两者的区别如下所示:

十进制形式:指的是数字必须以整数形式+小数形式组成,比如 10.0 、3.14 ......符合规则,以10为底数,并且科学计数法要在范围值之内。

指数形式 :一般数学上对于小数可以以10为底进行表示 比如3.14 * 10²,但是在使用英文半角输入法的时候没办法输入上底或者下底,所以C语言规定以字母e或者E来表示指数,并且要求字母e或者E的前面必须有数字,字母e或者E的后面必须为整数。

eg:

-3.14E-2   2E-3   0.3E4

printf("%e", 10000000.00);

所以:

E3 错误 因为E的前面要有数据 比如说 3.14E3

3.1e5.6 错误 因为 E的后面必须是整数

3.1e-2 对的 相当于3.1*10(-2次方)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值