01__C语言入门

一、C语言的基本结构

(1)、第一个C程序:hello world

配置部署好 vsCode 之后,就可以直接在上面写代码了,新建一个新的C程序文件,向屏幕输出一串字符 “Hello World!”

下面,从整体上来分析一下这个最简单的C语言程序,将这个最简程序的各个部分剖析清楚,明白我们写下的每一个字符的具体含义。

实例代码1:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    printf("hello world!\n");
    return 0;
}

示例代码2:

#include <stdio.h>              

extern int funcA(void);        
extern int num;                

int main(int argc, char const *argv[])
{
    printf("hello world!\n");   
    funcA();                    
    num = 200;                  
    return 0;
}
int num = 100;              
int funcA(void)         
{
    printf("hello GEC!\n");
    return 0;
}

(2)、第一个C程序结构解析

 1、头文件

#include <stdio.h>        // 告诉编译器在.h文件中(声明)有这么一个符号,你需要去其相应的.c文件里去找其源文件(实现(定义))
  1. C语言程序中,任何符号(包括变量和函数)的使用,都是需要提前声明的。
  2. 如果程序用到了系统库函数,那么就需要包含相应的系统头文件来进行声明。

上述代码中用到库函数printf,而这个函数的声明在头文件 stdio.h 中,因此在该程序中需要包含此头文件。

声明:

  • 概念:对源文件外定义的某个符号进行描述的过程,称为声明
  • 作用:经过声明的符号,编译器才能正确识别和编译,否则编译器不认识,无法判定语法错误
  • 符号:变量、函数等
  • 示例:
// 声明一个变量符号number
extern int number ;     

// 声明一个函数符号function
extern void function(int size, char *buf);

// 注意:前面的extern的关键字是可以不加的,但是建议初学者一定要加

2、主函数

  1. 主函数是必须有的,每一个C语言程序都有main函数,哪怕是空的。
  2. 主函数的名字是固定的,叫 main ,这个函数名不可被挪作他用。
  3. 主函数是程序的入口,也就是程序开始运行的地方。
  4. 主函数分解如下:
// int:        返回值类型,代表主函数最终的执行结果是一个整型数据
// main:       main是函数名,这个名字不能变
// void:      是函数参数列表,可以省略,表示空的意思,就是没有参数的意思

int main(void)
{
   ........
}

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

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

}

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

3、printf函数(标准输出 --- 屏幕设备)

C语言被称为是一种面向过程的模块化语言,所谓的模块,指得是一个个功能明确、各司其职的封装函数,它们就像一块块积木,被合理有机地拼搭起来,形成复杂、健壮的程序。

在这之中,系统标准C库提供了非常多“模块”,printf 就是其中之一,它的功能就是:向终端输出一段指定格式的数据。

面向对象:我吃饭、我唱歌、我跳舞

面向过程:吃饭、唱歌、跳舞

// 向终端屏幕输出一段字符串
printf("Hello World!\n");

解析:

a、常见的格式控制符:

一、基础格式控制:
    %d        // 十进制整数,decimalism
    %o        // 八进制整数,octonary
    %x          // 十六进制整数,hexadecimal
    %c        // 字符,character    
    %s        // 字符串,character string
    %f        // 单精度浮点数,float
    %p        // 输出地址、输出指针的值,pointer
 
二、格式控制拓展:
    .........

示例代码:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int num       = 100;        // 定义一个整型类型的num变量,并给其赋初始值为100
    char buf[128] = "shijienameda,woxiangdainiqukankan";  // 定义一个char型数组(char*类型),里面存放了一串字符

    float f1      = 3.14;       // 定义了一个单精度浮点型的变量,并给其赋初始值为3.14
    double f2     = 3.14;       // 定义了一个双精度浮点型的变量,并给其赋初始值为3.14

    // 1、没有格式控制符的printf函数
    printf("hello world!\n");

    // 2、打印整型数
    printf("整型数 = %d\n", num);        // 要求打印num这个变量的时候,用十进制数表示:decimalism

    // 3、打印八进制数
    printf("八进制数 = %o\n", num);       // 要求打印num这个变量的时候,用八进制数表示:octonary

    // 4、打印十六进制数
    printf("十六进制数 = %x\n", num);     // 要求打印num这个变量的时候,用十六进制数表示:hexadecimal

    // 5、打印字符(本质上是一个整型)
    printf("字符 = %c\n", num);          // 要求打印num这个变量的时候,用字符表示:character
    /*
        一开始计算机中是没有固定的数据(1010....)来表示字符的(abcdefg.....)
        所以后面定了一个标准:ASCLL表(这个表描述了相关字符(128个字符)对应的数据(0-127))
    */

    // 6、打印字符串
    printf("buf = %s\n", buf);          // 要求打印buf这个变量的时候,用字符串类型(数组类型)(char*指针类型)表示:character string
    /*
        printf("字符串 = %s\n", num); 
        因为num变量不是字符串类型的,所以会发生类型不匹配的情况
        warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
        printf("字符串 = %s\n", num);
        格式%s要求参数类型为char *类型,但是printf函数的参数2的类型却是int类型
    */

    // 7、打印小数(单精度浮点型)
    printf("小数(单精度) = %f\n", f1);      // 要求打印f1这个变量的时候,用单精度浮点型表示:float

    // 8、打印小数(双精度浮点型)
    printf("小数(双精度) = %f\n", f2);      // 要求打印f2这个变量的时候,用双精度浮点型表示:double float
    /*
        笔试题:

            判断两个浮点型数据f1和f2的值是否一致
            if( f1 == f2)
            {
                printf("两个浮点型数据相等\n");
            }
            else
            {
                printf("两个浮点型数据不相等\n");
            }
    */

    // 9、打印地址数据(打印指针变量里面的数据(指针变量里面的数据就是地址))
    printf("num = %p\n", num);      // (假地址:0x64(本质上是值))已地址的形式,打印出num的值(地址使用十六进制数据来表示的)      
    printf("num = %p\n", &num);     // (真地址:0x7fff1d41d610)打印num变量的地址
    return 0;
}

b、常见转义字符、显示特效转义字符:

转义字符通常前面有\符号

一、基本转义字符
    \n - 换行符。将光标移动到下一行的开始位置。******
    \t - 水平制表符。通常会将光标移动到下一个制表位。
    \\ - 反斜杠。用来表示实际的反斜杠字符。  
    \' - 单引号。用来表示实际的单引号字符。
    \" - 双引号。用来表示实际的双引号字符。
    \? - 问号。虽然问号本身不需要转义,但在某些情况下为了防止与三字母序列混淆,可能会用到。
    \a - 警报声。发出警报声。
    \b - 退格。将光标向后移动一个字符的位置。
    \f - 换页。跳转到下一页的开始位置。
    \r - 回车。将光标移动到当前行的开始位置,但不换行。
    \v - 垂直制表符。通常会将光标移动到下方的垂直制表位。
    \ooo - 其中ooo是1到3位的八进制数
    \xhh - 其中hh...是一个或多个十六进制数字。(\101 和 \x41 都代表大写字母 'A' 的ASCII码值65)
    

二、背景色、字体色显示转义字符
    a、格式:\033[40-47;30-37m
    b、说明:
        40/30:   黑色(背景色/字体色)
        41/31:   红色
        42/32:   绿色
        43/33:   黄色
        44/34:   蓝色
        45/35:   紫色
        46/36:   深绿色
        47/37:   白色
    c、使用:
        printf("\033[40;32m《学生信息管理系统》\n");

三、显示效果转义字符
    \033[0m           // 关闭特效
    \033[1m           // 高亮效果
    \033[4m           // 下划线效果
    \033[5m           // 闪烁效果(只有ubuntu18.04系统具备这个效果)
    \033[7m           // 反显(交换前景色和背景色)
    \033[8m           // 消隐(文本不可见)


四、光标设置
    \033[2J           // 清除屏幕
    \033[x;yH         // 定位光标(x:横轴坐标, y:纵轴坐标)
    \033[yA           // 上移光标(y是纵轴移动的位置)
    \033[yB           // 下移光标
    \033[xC           // 右移光标(x是横轴移动的位置)
    \033[xD           // 左移光标
    \033[H            // 复位光标
    \033[?25l         // 隐藏光标
    \033[?25h         // 显示光标
    \033[u            // 恢复光标位置
    \033[s            // 保存光标位置
    \033[K            // 清除从光标到行尾的内容

4、return语句

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

int main(void)
{
    ... ...
    // 一般而言,函数正常退出返回0,非正常退出返回非0
    return 0;
}

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

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

二、man帮助手册、在线文档的使用(第一手资料)

(1)、man手册(manual:手动的)

编程开发的过程中,需要使用众多的系统指令、各类函数库、系统调用、各类系统脚本文件等,这些种类繁多、功能各异的信息,可以通过统一的man手册来获取第一手资料(英文),man文档是帮助信息的权威通道,是大多数教程、书籍的知识来源。

由于 man 手册所需要罗列的帮助条目众多,因此 man 手册被妥善地分为9册,不同的帮助信息被放入对应的man分册中:

  • 在ubuntu命令行中敲::
man man

man文档的九个分册:

  1. 可执行程序或Shell命令(默认已安装)
  2. 系统调用 (Linux内核自带的函数)
  3. 库函数 (外部的第三方函数)
  4. 特殊文件(通常出现在/dev目录下)
  5. 文件的特殊格式或协定(例如/etc/passwd的格式)
  6. 游戏
  7. 杂项(例如一些宏定义)
  8. 系统管理员命令(通常只能由管理员执行)
  9. 非标准内核例程

a、man手册的安装

在默认情况下,系统只安装第一册,其他的帮助信息一般需要用户自己手动安装,安装指令如下:

gec@ubuntu:~$ sudo apt install manpages
gec@ubuntu:~$ sudo apt install manpages-dev

b、man手册的查询

使用man手册查询命令、函数时,一般直接在man后面接上待查条目即可,但有时候会遇到同一个待查询的条目存在于多个man分册的情况,这就需要先罗列出该条目所在的分册信息,然后再根据需要去选择帮助文档的序号。

1、查询单一分册的条目:
gec@ubuntu:~$ man strcpy

2、查询存在于多个分册的条目:
# 先使用 -f 来查看有哪些分册包含了该条目
gec@ubuntu:~$ man -f printf
printf (1)           - format and print data
printf (3)           - print formatted output

# 根据需要,指定查询某一册帮助分册
gec@ubuntu:~$ man 3 printf

c、man手册的使用

#include <stdio.h>
#include <string.h> // 向编译器声明strlen这个函数,方便编译器后面遇到它的时候,进行跳转

/*
    使用man手册,来查询一个strlen函数的使用方法
    1、在ubuntu系统终端上敲命令:man -f strlen           // 查看该函数的man手册有几册,选择相应的手册数进行查询
    2、man 3 strlen                                     // 阅读打开man手册文档
    3、如何使用一个函数??
        a、函数的作用(NAME)
            strlen - calculate the length of a string   // 计算字符串的长度 

        b、函数的头文件(SYNOPSIS)
            #include <string.h>
        
        c、函数原型解析(DESCRIPTION)
            size_t strlen(const char *s);
            参数一:要计算长度的字符串变量

            The strlen() function calculates the length of the string s, excluding the terminating null byte ('\0').
            // 翻译:这个strlen函数会计算s这个字符串的长度,但是不包括结束符\0

        d、函数的返回值(RETURN VALUE)
            返回字符串的字节数(这个字符串有多少个字符)
*/
int main(int argc, char const *argv[])
{

    char buf[128] = "nihao";     // 创建128个字符空间大小的内存,并将字符串内容,给赋值进去
    size_t len = strlen(buf);    // 使用字符串函数strlen,去计算buf内存里面有几个字符(其中不包括\0字符)
    printf("len = %lu\n", len);  // 由于size_t是long unsigned int数据类型,所以此处的格式控制符应为lud(其中d省略)
    return 0;
}

(2)、在线文档(C/C++)

https://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5

三、代码风格规范

1、标识符命名规则(变量名、函数名等):

  • 只能包含数字、字母以及下划线,不能包含其他任何特殊字符。
  • 只能以字母或者下划线开头。
  • 不能跟系统已有的关键字重名,也不能跟本命名空间(namespace)中具有相同作用域的其他标识符重名。
  • 尽量能一望便知,做到顾名思义,避免使用无意义字符

通常的命名方式(推荐):

(1)、函数名的命名方法:
1、驼峰命名法:  FangHuiQing   // 一般在面向对象开发的时候多使用
2、下划线命名法: fang_hui_qing // 一般在面向过程开发的时候多使用
3、二合一法:    Fang_HuiQing  // LED_InitDev(), LED_CloseDev(), LED_OpenDev(); 前面的命名表示文件名(led.c),后面表示函数功能 

(2)、变量名的命名方法:
下划线命名法(小写): int led_num; int led_flag;  // 前面的名字,能够让我们知道这个变量是哪个功能或是哪个文件的变量,后面的名字可以让我们知道是什么样的功能

(3)、宏定义
下划线命名法(小写): #define LED_ON 1

2、缩进:凡是有代码块的地方都必须缩进,一对大括号 { } 代表一个代码块

3、空格:标点符号后面,一般加空格

4、空行:不同逻辑段落中间,一般加空行

5、排版的快捷方式

让代码块整体左移: 选中代码块+shift键+tab键

让代码块整体右移: 选中代码块+tab键

注释/解除注释: 选中代码块+ctrl+/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bardb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值