C语言

1. C语言--初始C语言

Posted on 2022-01-30,14 min read

1. 初始C语言

1.1 介绍

广泛应用于底层开发(如:驱动)。有完整的美国国家标准语法,称为ANDI C。C语言是一门面向过程的的计算机语言。主要的编译器有Clang、GCC、WIN-TC、Turbo C等。

国际标准:C89、C90、C99、C11(C90之后的标准没有火起来)

1.2 第一个C程序

1.2.1 编译器

Visual Studio、Dev C++、Visual C++ 6.0、GCC、Clang、Pelles C、Watcom C/C++、Tiny C Compiler、Code::Blocks、Turbo C、C-Free等

1.2.2 继承开发环境(IDE)

VS2013/VS2019:集成开发环境,集成了windows下的C语言编译器

1.2.3 文件

  • xxx.c 源文件
  • xxx.h 头文件

1.2.4 步骤

  • 创建项目

  • 创建源文件







  • 编写代码

    • 主函数(main函数)
    #include <stdio.h>
    
    int main()
    {
      printf("Hello World!");
      return 0;
    }
    


  • 编译、链接、运行代码



1.2.5 补充

  • 一个项目中可以有多个.c文件
  • 多个.c文件中有且仅有一个main函数

1.3 基本数据类型

在 C 语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储的位模式。

1.3.1 整数类型

short (int)
int
long (int)
long long (int)
// 不同数据类型的大小因不同的计算机系统而异
// 编译器可以决定数据类型的大小但必须保证:short <= int <= long <= long long

1.3.2 浮点类型

float // 单精度浮点型
double // 双精度浮点型

1.3.3 字符型

char // 可以当作整数类型处理


1.3.4 sizeof运算符

// sizeof(type) 得到对象或类型的存储字节大小
// 使用sizeof查看数据类型大小
int main()
{
  printf("size of short %d\n", sizeof(short));
  printf("size of short %d\n", sizeof(int));
  printf("size of short %d\n", sizeof(long));
  printf("size of short %d\n", sizeof(long long));
  printf("size of short %d\n", sizeof(float));
  printf("size of short %d\n", sizeof(double));
  return 0;
}


1.4 常量变量

1.4.1 变量

程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。

  • 变量定义
    告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表。

    type var_list;
    // type为C数据类型或自定义的对象
    // var_list由一个或多个标识符组成,多个标识符之间使用逗号隔开
    // eg:
    int a, b;
    char c;
    
    // 初始化:变量可以在声明时初始化(指定一个初始值)
    // eg:
    int a = 666;
    int x = 3, y = 4;
    
  • 变量声明
    向编译器保证变量以指定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。

    变量声明的两种情况:
      1.需要建立存储空间。int a; 在声明时建立了存储空间
      2.不需要建立存储空间。extern关键字声明变量而不定义 extern int a 其中变量a可以在其他c文件中定义
        除非有extern关键字,其余都是变量的定义
    
    
  • 左值和右值

    • 左值(lvalue):指向内存位置的表达式。左值可以出现在赋值号的左边或右边。变量时左值。
    • 右值(rvalue):存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。数值型字面量是右值。

1.4.2 常量

固定值。程序执行期间不会改变。又称为字面量。

  • 可以是任何数据类型。比如:整数常量、浮点常量、字符常量、字符串字面值、枚举常量。
  • 可认为是常规的变量,只不过在定义后不能修改。
  • 转义字符:特定字符前有反斜杠,具有特殊含义。
/*
常量定义的方式:
  1. #define预处理器
     格式:#define identifier value
  2. const关键字(const声明常量要在一条语句内完成)
     格式:const type variable = value;
  3. 枚举常量(本质:数字由字符来表达)
     格式:enum 枚举类型名称 {符号变量a, 符号变量b, 符号变量c}; a、b、c的值从零开始递增
          指定值:enum COLOR {red=1,yellow,green=5}; 则red=1,yellow=2,green=5(默认递增)
     重点:枚举类型只能是int
*/

1.5 字符串

本质:使用null字符\0终止的一维字符数组

1.6 注释

解释代码

// C++注释风格,最后引入C语言中/*C语言注释风格不支持嵌套注释*/


1.7 选择语句

/*分支语句*/
int main() {
  int a = 1;
  if (a==1)
  {
    printf("a = 1");
  }
  else
  {
    printf("a != 1");
  }
  return 0;
}


当if或else内只有一条语句时可省略大括号

1.8 循环语句

/* 循环语句 */int main() {  int line = 0;  while (line < 30000)  {    printf("coding: %d\n", line);    line++;  }  if (line==30000)  {    printf("进大厂 拿高薪\n");  }  return 0;}


while循环内只有一条语句时可省略大括号

1.9 函数

/* 函数 */int main(){  int a = 3;  int b = 4;  int result = 0;  result = Add(a, b);  printf("result => %d\n", result);  return 0;}int Add(int x, int y){  int result = 0;  result = x + y;  return result;}


1.10 数组

一组相同类型的元素的集合

// 数组int main(){  // 创建  int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };  // 其中arr为数组名 int为数组中每个元素的类型 10为数组中元素的个数  char ch[10] = { 'a', 'b', 'c', 'd', 'e' }; // 不完全初始化,其余值默认为0  // 访问(利用每个元素的下标 索引从零开始依次往后)  int i = 0;  while (i<10)  {    printf("arr[%d] => %d\n", i, arr[i]);    i++;  }  return 0;}


1.11 操作符

1.11.1 算数操作符

+ - * / %

1.11.2 移位操作符

>> <<

1.11.3 位操作符

& 按位与| 按位或^ 按位异或

1.11.4 赋值操作符

= += -= *= /= >>= <<=

1.11.5 单目操作符

! // 逻辑非运算符~ // 按位取反运算符++ -- // 自增自减运算符- // 负号运算符(type) // 类型转换运算符*和& // 指针运算符和取地址运算符sizeof // 长度运算符 sizeof求变量时后面的括号可以省略 求类型时不可以省略       // sizeof(int) sizeof(a)       // 可以计算数组,单位是字节

1.11.6 关系操作符

==
!=
>
>=
<
<=

1.11.7 逻辑运算符

&& // 逻辑与
|| // 逻辑或
!  // 逻辑非

1.11.8 条件操作符

// 三目操作符
exp1 ? exp2 : exp3;
// exp1成立,exp2执行,整个表达式的结果为exp2的结果
// exp1不成立,exp3执行,整个表达式结果为exp3的结果

1.11.9 逗号表达式

// 逗号隔开的一串表达式
exp1, exp2, exp3;
eg: (2, 2+1, 2+2, 2+3);
// 从前往后计算,整个表达式的结果是最后一个表达式的结果

1.11.10 其他

[] // 下标引用操作符() // 函数调用操作符.->
  • 自增/自减

    // 前置++: 先++后使用int main(){  int a = 6;  int b = ++a;  printf("%d\n", a); // 7  printf("%d\n", b); // 7  return 0;}
    


    // 后置++: 先使用后++int main(){  int a = 6;  int b = a++;  printf("%d\n", a); // 7  printf("%d\n", b); // 7  return 0;}
    


  • 强制类型转换

    int main() 
    {
      int pi = (int)3.1415926;
      return 0;
    }
    
    

1.12 关键字(32个)

C语言保留的一些有特殊作用词语。变量名不能是关键字。

auto     声明自动变量。自动创建、自动销毁。修饰局部变量,可省略。
double   声明双精度变量或函数
typedef  用以给数据类型取别名
register 声明寄存器变量
short    声明短整型变量或函数
char     声明字符型变量或函数
const    声明只读变量
static   声明静态变量
int      声明整型变量或函数
struct   声明结构体变量或函数
unsigned 声明无符号类型变量或函数
volatile 说明变量在程序执行中可被隐含地改变
long     声明长整型变量或函数
union    声明共用数据类型,共用体
signed   声明有符号类型变量或函数
void     声明函数无返回值或无参数,声明无类型指针
float    声明浮点型变量或函数
enum     声明枚举类型
extern   声明变量是在其他文件正声明
if       条件语句
else     条件语句否定分支(与 if 连用)
switch   用于开关语句
case     开关语句分支
for      一种循环语句
do       循环语句的循环体
while    循环语句的循环条件
goto     无条件跳转语句
continue 结束当前循环,开始下一轮循环
break    跳出当前循环
default  开关语句中的"其他"分支
sizeof   计算数据类型长度
return   子程序返回语句(可以带参数,也可不带参数)循环条件

其他

define、include不是关键字,是预处理指令 
  • typedef

    // 类型别名 类型重命名 用来简化代码
    


  • static

    /*三种用法:  1.修饰局部变量:局部变量生命周期延长(本质:改变了数据类型,从栈区->静态区)  2.修饰全局变量:使全局变量只能在自己所在的源文件.c内部使用,即使在其他源文件种声明也不能使用改全局变量  3.修饰函数:使函数只能在自己的内部源文件.c种使用,项目中其他源文件不能使用*/ 
    

    示例

    1. static修饰局部变量

    2. static修饰全局变量

    3. static修饰函数

1.13 define

define使预处理指令

/*作用:  1. 定义常量  2. 定义宏(宏用来完成替换)*/

1.13.1 定义变量


1.13.2 定义宏


// 宏只完成替换// 为保证正常运行,应使用小括号将函数体括起来


1.14 指针

指针描述了数据在内存中的位置(内存地址),标示了一个占据存储空间的实体。 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。

1.14.1 指针变量的声明

// 格式;type *var_name;// type使指针的基类型,*表示该变量是一个指针变量,var_name使变量名// eg:int* pi;double* pd;

1.14.2 指针变量的大小

// 在32位系统种,指针变量大小为4byte// 在64位系统种,指针变量大小位8byte// 指针变量大小与指针指向的数据类型无关// 下图为64位系统种,指针大小演示:


1.14.2 访问数据地址

// 格式:
&var_name
// 通过&获取var_name所在的内存地址
// eg:
int main() 
{
  int a = 666;
  int* pa = &a; // 去除变量a的地址并赋值给指针变量pa
  printf("%p\n", pa);
  return 0;
}


1.14.3 NULL指针

// NULL指针:空指针,是一个定义在标准库中的值为零的常量。


在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。

1.15 结构体

结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。结构用于表示一条记录。

1.15.1 定义

// 格式:struct 结构体名 {     结构体所包含的变量};// eg:struct Student{  char name[16]; // 姓名  int age;       // 年龄  double height; // 身高};

1.15.2 结构体变量

  • 定义结构体时定义结构体变量

    struct Student
    {
      char name[16]; // 姓名
      int age;       // 年龄
      double height; // 身高
    } s1, s2;
    // 将变量放在结构体的最后
    
  • 如果只需要是使用s1和s2,此后不再使用结构体,则可省略结构体名称

    struct{
      char name[16]; // 姓名
      int age;       // 年龄
      double height; // 身高
    } s1, s2;
    

1.15.3 成员获取和赋值

  • 获取

    // 1).结构体变量名.成员名
    printf("name: %s, age: %d, height: %lf\n", s.name, s.age, s.height);
    // 2).结构体指针变量名->成员名
    struct Student* ps = &s;
    printf("name: %s, age: %d, height: %lf\n", (*ps).name, (*ps).age, (*ps).height);
    printf("name: %s, age: %d, height: %lf\n", ps->name, ps->age, ps->height);
    
  • 赋值

    // 1).单个赋值:结构体变量名.成员名 = "Value";
    // 2).整体赋值,eg:
    //    a.定义结构体时整体赋值:
          struct{
            char name[16]; // 姓名
            int age;       // 年龄
            double height; // 身高
          } s = {"listen", 20, 180.5};
    //    b.定义结构体后整体赋值:
          struct Student s = {"listen", 20, 185};
    
    // 结构体是创建变量的模板,不占用内存空间
    // -> 先找到指针指向的对象,再找到他的成员