C语言---基础内容(万字)

C 语言是一种通用的、面向过程式的计算机程序设计语言。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇在贝尔电话实验室设计开发了 C 语言。

C 语言是一种广泛使用的计算机语言,它与 Java 编程语言一样普及,二者在现代软件程序员之间都得到广泛使用。

当前最新的 C 语言标准为 C18 ,在它之前的 C 语言标准有 C17、C11...C99 等。那么

为什么要使用 C?

C 语言最初是用于系统开发工作,特别是组成操作系统的程序。由于 C 语言所产生的代码运行速度与汇编语言编写的代码运行速度几乎一样,所以采用 C 语言作为系统开发语言。下面列举几个使用 C 的实例:

  • 操作系统
  • 语言编译器
  • 汇编器
  • 文本编辑器
  • 打印机
  • 网络驱动器
  • 现代程序
  • 数据库
  • 语言解释器
  • 实体工具
编译工具:

C 程序

一个 C 语言程序,可以是 3 行,也可以是数百万行,它可以写在一个或多个扩展名为 ".c" 的文本文件中,例如,hello.c 。您可以使用 "vi""vim" 或任何其他文本编辑器来编写您的 C 语言程序。

C 程序的结构

C 程序主要包括以下部分:

  • 预处理器指令
  • 函数
  • 变量
  • 语句 & 表达式
  • 注释

以下是一个简单例子:

#include <stdio.h>
 
int main()
{
    /* 我的第一个 C 程序 */
    printf("Hello, World! \n");
 
    return 0;
}

解析:

  • 所有的 C 语言程序都需要包含 main() 函数。 代码从 main() 函数开始执行。
  • / ... / 用于注释说明。
  • printf() 用于格式化输出到屏幕。printf() 函数在 "stdio.h" 头文件中声明。
  • "\n"表示输出后换行。
  • stdio.h 是一个头文件 (标准输入输出头文件)
  • #include 是一个预处理命令,用来引入头文件。
  • return 0; 语句用于表示退出程序。 终止 main() 函数,并返回值 0

C 基本语法

分号

在 C 程序中,分号是语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。

例如,下面是两个不同的语句

printf("Hello, World! \n");
return 0;
注释

**C 语言有两种注释方式

/* 单行注释 */  或者 //单行注释
/* 
 多行注释
 多行注释
 多行注释
 */
标识符
  • C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。
  • 一个标识符以字母、下划线开始,后跟零个或多个字母、下划线和数字。注意不能由数字开头!
  • C 标识符内不允许出现标点字符,比如 @、$ 和 %。C 是区分大小写的编程语言。
  • 因此,在 C 中,Manpowermanpower 是两个不同的标识符。下面列出几个有效的标识符:
    mohd zara abc move_name a_123
    myname50 _temp j a23b9 retVal
关键字

保留字不能作为常量名、变量名或其他标识符名称。

auto  double int struct break else long switch

case enum register typedef char extern return union

const float short unsigned continue for signed void

default goto sizeof volatile do if while static

基本数据类型

1.变量、常量和字面量
变量

在编程中,变量是用于保存数据的容器(存储区)。

为了指定存储区域,应该为每个变量赋予唯一的名称(标识符)。变量名称只是存储位置的符号表示。例如:

示例

int playerScore = 95;

在这里,playerScore是一个int类型变量。为这个变量分配了一个整数值95。

变量的值可以更改,因此可以更改名称。

示例

char ch = 'a';
// some code
ch = 'l';
变量命名规则
  1. 变量名称只能包含字母(大写和小写字母),数字和下划线。

  2. 变量的第一个字母应该是字母或下划线。

  3. 对于变量名称(标识符)可以使用多长没有指定。但是,如果变量名超过31个字符,则在某些编译器中可能会遇到问题。

**注意:*应始终尝试为变量赋予有意义的名称。例如:firstName是比fn更好的变量名。

C 语言是一种强类型语言。意味着变量类型一旦声明就无法更改。例如:

示例

int number = 5;      //整型变量
number = 5.5;        // error
double number;       // error

在这里,number变量的类型为int。您不能分配浮点(十进制)值5.5给这个变量。另外,您不能将变量的数据类型重新定义为double(双精度浮点型)。顺便说一下,要将十进制值存储在C中,您需要将其类型声明为double 或 float。

字面量

字面量是用于表示固定值的数据。它们可以直接在代码中使用。例如:1,2.5,'c'等。

这里1,2.5和'c'是字面量。为什么?您不能为这些项分配不同的值。

整数

整数是没有任何小数或指数部分的数字文字(与数字关联)。C编程语言中有三种类型的整数字面量:

  • 八进制(以8为底)
  • 十进制(以10为底)
  • 十六进制(以16为底)

例如:

十进制: 0, -9, 22 etc

八进制: 021, 077, 033 etc

十六进制: 0x7f, 0x2a, 0x521 etc

在C编程中,八进制以0开头,十六进制以0x开头。

浮点字面量

浮点字面量是具有分数形式或指数形式的数字字面值。例如:

-2.0

0.0000234

-0.22E-5

注意:指数型数值E前后必须为整数

字符

通过将单个字符括在单引号内来创建字符字面量。例如:'a','m','F','2','}'等。

转义序列

有时,在C编程中必须使用不能键入或具有特殊含义的字符。例如:换行符(输入),制表符,问号等。

为了使用这些字符,使用了转义序列。

转义字符序列

转义序列 字符
\b 退格符
\f 换页符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ 反斜杠
\' 单引号
\'' 双引号
\? 问号
\0 空字符

例如:\n用于换行符。反斜杠\会导致编译器无法正常处理字符。

字符串

字符串字面量是用双引号引起来的一系列字符。例如:

"good" //字符串常量

"" //空字符串常量

" " //六个空格的字符串常量

"x" //具有单个字符的字符串常量。

"Earth is round\n" //用换行符打印字符串

常量

如果要定义一个不能更改其值的变量,则可以使用 const关键字。这将创建一个常量。例如,

示例

const double PI = 3.14;

注意,我们增加了关键字 const。

在这里,PI是一个符号常量;其值不能更改。

示例

const double PI = 3.14;
PI = 2.9; //错误

也可以使用#define预处理器指令定义常量。

#define PI  3.12133

C语言基本输入输出

格式说明符
  • %d 对应为 int
  • %f 对应为 float
  • %lf 对应为 double
  • %c 对应为 char
所占字节
类型                  所占字节
int                     4
float                   4
double                  8
char                    1
short                   2

printf()输出函数

该函数将格式化的输出发送到屏幕

示例一:printf()简单输出
#include <stdio.h>    
int main()
{ 
    //打印输出引号内的字符串
    printf("C Programming");
    return 0;
}

该程序如何工作?

  • 所有有效的C程序都必须包含该main()函数。代码从main()函数的开头开始执行。

  • printf()是一个库函数来格式化输出发送到屏幕上。该函数将打印引号内字符串。

  • 要在我们的程序中使用printf()函数,我们需要使用#include <stdio.h>语句包括stdio.h头文件 。

  • return 0;main()函数中的语句是程序的"退出状态"。 它是可选的。

示例2:整数输出
#include <stdio.h>
int main()
{
    int a = 5;
    printf("Number = %d", a);
    return 0;
}

使用%d格式说明符来打印int类型。在这里,引号内的%d将替换为testInteger的值。

示例3:单精度浮点和双精度浮点数输出
#include <stdio.h>
int main()
{
    float number1 = 13.5;
    double number2 = 12.4;

    printf("number1 = %f\n", number1);
    printf("number2 = %lf", number2);
    return 0;
}

输出结果

number1 = 13.500000
number2 = 12.400000

要打印float,使用%f格式说明符。同样,还要使用%lf打印double值。

示例4:打印字符
#include <stdio.h>
int main()
{
    char chr = 'a';    
    printf("character = %c.", chr);  
    return 0;
}

要打印char,使用%c格式说明符。

scanf()输入函数

作用是从用户那里接受输入。该函数从标准输入(例如键盘)读取格式化的输入。

示例5:整数输入/输出
#include <stdio.h>
int main()
{
    int testInteger;
    printf("输入数字: ");
    scanf("%d", &testInteger);  
    printf("Number = %d",testInteger);
    return 0;
}

输出结果

输入数字: 4
Number = 4

在这里,使用了scanf()函数内部的格式%d说明符来接收用户的输入int数值。用户输入整数时,它将存储在testInteger变量中。

注意,scanf()使用了&testIntegerinside 。这是因为&testInteger获取的地址testInteger,并且用户输入的值存储在该地址中。

示例6:单精度浮点和双精度浮点数输入/输出
#include <stdio.h>
int main()
{
    float num1;
    double num2;

    printf("输入一个数字: ");
    scanf("%f", &num1);
    printf("输入另一个数字: ");
    scanf("%lf", &num2);

    printf("num1 = %f\n", num1);
    printf("num2 = %lf", num2);

    return 0;
}

输出结果

输入一个数字: 12.523
输入另一个数字: 10.2
num1 = 12.523000
num2 = 10.200000

float和double分别使用%f和%lf格式说明符。

示例7:C 字符 I / O
#include <stdio.h>
int main()
{
    char chr;
    printf("输入一个字符: ");
    scanf("%c",&chr);     
    printf("您输入了 %c.", chr);  
    return 0;
}

当用户在上述程序中输入字符时,字符本身不会被存储。而是存储一个整数值(ASCII值)。

当我们使用%c文本格式显示该值时,将显示输入的字符。如果%d用于显示字符,则将其ASCII值打印出来。

示例8:ASCII值
#include <stdio.h>
int main()
{
    char chr;
    printf("输入一个字符: ");
    scanf("%c", &chr);     

    //当使用%c时,将显示一个字符
    printf("您输入了 %c.\n",chr);  

    //使用%d时,显示ASCII值
    printf("ASCII 值为 % d.", chr);  
    return 0;
}

输出结果

输入一个字符: g
您输入了 g.
ASCII 值为 103.
多个值输入输出(I/O)

这是可以从用户那里获取多个输入并显示它们的方法示例

#include <stdio.h>
int main()
{
    int a;
    float b;

    printf("输入整数,然后再输入浮点数: ");
  
    //接受多个输入
    scanf("%d%f", &a, &b);

    printf("您输入了%d和 %f", a, b);  
    return 0;
}

输出结果

输入整数,然后再输入浮点数: -3
3.4
您输入了 -3 和 3.400000

算术运算符、赋值运算符及其对应表达式的应用

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符,并提供了以下类型的运算符:

  • 算术运算符

  • 关系运算符

  • 逻辑运算符

  • 位运算符

  • 赋值运算符

算术运算符

下表显示了 C 语言支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:

运算符 描述 示例
+ 把两个操作数相加 A + B 将得到 30
- 从第一个操作数中减去第二个操作数 A - B 将得到 -10
* 把两个操作数相乘 A * B 将得到 200
/ 分子除以分母 B / A 将得到 2
% 取模运算符,整除后的余数 B % A 将得到 0
++ 自增运算符,整数值增加 1 A++ 将得到 11
-- 自减运算符,整数值减少 1 A-- 将得到 9

看下面的示例,了解 C 语言中所有可用的算术运算符:

#include <stdio.h>
int main()
{
   int a = 21;
   int b = 10;
   int c ;
 
   c = a + b;
   printf(" c = a + b 的值是 %d\n", c );  //31
   c = a - b;
   printf(" c = a - b 的值是 %d\n", c );  //11
   c = a * b;
   printf(" c = a * b 的值是 %d\n", c );  //210
   c = a / b;
   printf(" c = a / b 的值是 %d\n", c );  //2
   c = a % b;
   printf(" c = a % b 的值是 %d\n", c );  //1
   c = a++;  // 赋值后再加 1 ,c 为 21,a 为 22
   printf(" c = a++ 的值是 %d\n", c );    //21
   c = a--;  // 赋值后再减 1 ,c 为 22 ,a 为 21
   printf(" c = a-- 的值是 %d\n", c );    //22
 
}

以下示例演示了 a++ 与 ++a 的区别:

#include <stdio.h>
int main()
{
   int c;
   int a = 10;
   c = a++; 
   printf("先赋值后运算:\n");
   printf("Line 1 - c 的值是 %d\n", c );
   printf("Line 2 - a 的值是 %d\n", a );
   a = 10;
   c = a--; 
   printf("Line 3 - c 的值是 %d\n", c );
   printf("Line 4 - a 的值是 %d\n", a );
 
   printf("先运算后赋值:\n");
   a = 10;
   c = ++a; 
   printf("Line 5 - c 的值是 %d\n", c );
   printf("Line 6 - a 的值是 %d\n", a );
   a = 10;
   c = --a; 
   printf("Line 7 - c 的值是 %d\n", c );
   printf("Line 8 - a 的值是 %d\n", a );
 
}

以上程序执行输出结果为:

先赋值后运算:
Line 1 - c 的值是 10
Line 2 - a 的值是 11
Line 3 - c 的值是 10
Line 4 - a 的值是 9
先运算后赋值:
Line 5 - c 的值是 11
Line 6 - a 的值是 11
Line 7 - c 的值是 9
Line 8 - a 的值是 9

这里记住一句话:++在后表达式即原值

关系运算符

下表显示了 C 语言支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:

运算符 描述 示例
== 检查两个操作数的值是否相等,如果相等则条件为真。 (A == B) 为假。
!= 检查两个操作数的值是否相等,如果不相等则条件为真。 (A != B) 为真。
> 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 (A > B) 为假。
< 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 (A < B) 为真。
>= 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 (A >= B) 为假。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 (A <= B) 为真。

看下面的示例,了解 C 语言中所有可用的关系运算符:

#include <stdio.h>
 
int main()
{
   int a = 21;
   int b = 10;
   int c ;
 
   if( a == b )
   { 
   printf("Line 1 - a 等于 b\n" );
   }
   else
   {
      printf("Line 1 - a 不等于 b\n" );
   }
   if ( a < b )
   {
      printf("Line 2 - a 小于 b\n" );
   }
   else
   {
      printf("Line 2 - a 不小于 b\n" );
   }
   if ( a > b )
   {
      printf("Line 3 - a 大于 b\n" );
   }
   else
   {
      printf("Line 3 - a 不大于 b\n" );
   }
   /* 改变 a 和 b 的值 */
   a = 5;
   b = 20;
   if ( a <= b )
   {
      printf("Line 4 - a 小于或等于 b\n" );
   }
   if ( b >= a )
   {
      printf("Line 5 - b 大于或等于 a\n" );
   }
}

输出结果:

Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 a

逻辑运算符

下表显示了 C 语言支持的所有关系逻辑运算符。假设变量 A 的值为 1,变量 B 的值为 0,则:

运算符 描述 示例
&& 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A && B) 为假。
| 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 (A | B) 为真。
! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 !(A && B) 为真。

看下面的示例,了解 C 语言中所有可用的逻辑运算符:

#include <stdio.h>
 
int main()
{
   int a = 5;
   int b = 20;
   int c ;
 
   if ( a && b )
   {
      printf("Line 1 - 条件为真\n" );
   }
   if ( a || b )
   {
      printf("Line 2 - 条件为真\n" );
   }
   /* 改变 a 和 b 的值 */
   a = 0;
   b = 10;
   if ( a && b )
   {
      printf("Line 3 - 条件为真\n" );
   }
   else
   {
      printf("Line 3 - 条件为假\n" );
   }
   if ( !(a && b) )
   {
      printf("Line 4 - 条件为真\n" );
   }
}

输出结果:

Line 1 - 条件为真
Line 2 - 条件为真
Line 3 - 条件为假
Line 4 - 条件为真

赋值运算符

下表列出了 C 语言支持的赋值运算符:

运算符 描述 示例
= 简单的赋值运算符,把右边操作数的值赋给左边操作数 C = A + B 将把 A + B 的值赋给 C
+= 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 C += A 相当于 C = C + A
-= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 C -= A 相当于 C = C - A
*= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 C *= A 相当于 C = C * A
/= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 C /= A 相当于 C = C / A
%= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C %= A 相当于 C = C % A
<<= 左移且赋值运算符 C <<= 2 等同于 C = C << 2
>>= 右移且赋值运算符 C >>= 2 等同于 C = C >> 2
&= 按位与且赋值运算符 C &= 2 等同于 C = C & 2
^= 按位异或且赋值运算符 C ^= 2 等同于 C = C ^ 2
|= 按位或且赋值运算符 C |= 2 等同于 C = C | 2

示例

#include <stdio.h>
 
main()
{
   int a = 21;
   int c ;
 
   c =  a;
   printf("Line 1 - =  运算符示例,c 的值 = %d\n", c );
 
   c +=  a;
   printf("Line 2 - += 运算符示例,c 的值 = %d\n", c );
 
   c -=  a;
   printf("Line 3 - -= 运算符示例,c 的值 = %d\n", c );
 
   c *=  a;
   printf("Line 4 - *= 运算符示例,c 的值 = %d\n", c );
 
   c /=  a;
   printf("Line 5 - /= 运算符示例,c 的值 = %d\n", c );
 
   c  = 200;
   c %=  a;
   printf("Line 6 - %= 运算符示例,c 的值 = %d\n", c );
 
   c <<=  2;
   printf("Line 7 - <<= 运算符示例,c 的值 = %d\n", c );
 
   c >>=  2;
   printf("Line 8 - >>= 运算符示例,c 的值 = %d\n", c );
 
   c &=  2;
   printf("Line 9 - &= 运算符示例,c 的值 = %d\n", c );
 
   c ^=  2;
   printf("Line 10 - ^= 运算符示例,c 的值 = %d\n", c );
 
   c |=  2;
   printf("Line 11 - |= 运算符示例,c 的值 = %d\n", c );
 
}

当上面的代码被编译和执行时,它会产生下列结果:

Line 1 - =  运算符示例,c 的值 = 21
Line 2 - += 运算符示例,c 的值 = 42
Line 3 - -= 运算符示例,c 的值 = 21
Line 4 - *= 运算符示例,c 的值 = 441
Line 5 - /= 运算符示例,c 的值 = 21
Line 6 - %= 运算符示例,c 的值 = 11
Line 7 - <<= 运算符示例,c 的值 = 44
Line 8 - >>= 运算符示例,c 的值 = 11
Line 9 - &= 运算符示例,c 的值 = 2
Line 10 - ^= 运算符示例,c 的值 = 0
Line 11 - |= 运算符示例,c 的值 = 2

杂项运算符 ↦ sizeof & 三元

下表列出了 C 语言支持的其他一些重要的运算符,包括 sizeof? :

运算符 描述 示例
sizeof() 返回变量的大小。 sizeof(a) 将返回 4,其中 a 是整数。
& 返回变量的地址。 &a; 将给出变量的实际地址。
* 指向一个变量。 *a; 将指向一个变量。
? : 条件表达式 如果条件为真 ? 则值为 X : 否则值为 Y

示例

#include <stdio.h>
 
int main()
{
   int a = 4;
   short b;
   double c;
   int* ptr;
 
   /* sizeof 运算符示例 */
   printf("Line 1 - 变量 a 的大小 = %lu\n", sizeof(a) );
   printf("Line 2 - 变量 b 的大小 = %lu\n", sizeof(b) );
   printf("Line 3 - 变量 c 的大小 = %lu\n", sizeof(c) );
 
   /* & 和 * 运算符示例 */
   ptr = &a;    /* 'ptr' 现在包含 'a' 的地址 */
   printf("a 的值是 %d\n", a);
   printf("*ptr 是 %d\n", *ptr);
 
   /* 三元运算符示例 */
   a = 10;
   b = (a == 1) ? 20: 30;
   printf( "b 的值是 %d\n", b );
   b = (a == 10) ? 20: 30;
   printf( "b 的值是 %d\n", b );
}

当上面的代码被编译和执行时,它会产生下列结果:

Line 1 - 变量 a 的大小 = 4
Line 2 - 变量 b 的大小 = 2
Line 3 - 变量 c 的大小 = 8
a 的值是 4
*ptr 是 4
b 的值是 30
b 的值是 20

C 中的运算符优先级

运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。

例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。

下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。

类别 运算符 结合性
后缀 () [] -> . ++ - - 从左到右
一元 + - ! ~ ++ - - (type)* & sizeof 从右到左
乘除 * / % 从左到右
加减 + - 从左到右
移位 << >> 从左到右
关系 < <= > >= 从左到右
相等 == != 从左到右
位与 AND & 从左到右
位异或 XOR ^ 从左到右
位或 OR | 从左到右
逻辑与 AND && 从左到右
逻辑或 OR | 从左到右
条件 ?: 从右到左
赋值 = += -= *= /= %=>>= <<= &= ^= |= 从右到左
逗号 , 从左到右

示例

#include <stdio.h>
 
main()
{
   int a = 20;
   int b = 10;
   int c = 15;
   int d = 5;
   int e;
 
   e = (a + b) * c / d;      // ( 30 * 15 ) / 5
   printf("(a + b) * c / d 的值是 %d\n",  e );
 
   e = ((a + b) * c) / d;    // (30 * 15 ) / 5
   printf("((a + b) * c) / d 的值是 %d\n" ,  e );
 
   e = (a + b) * (c / d);   // (30) * (15/5)
   printf("(a + b) * (c / d) 的值是 %d\n",  e );
 
   e = a + (b * c) / d;     //  20 + (150/5)
   printf("a + (b * c) / d 的值是 %d\n" ,  e );
  
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

(a + b) * c / d 的值是 90
((a + b) * c) / d 的值是 90
(a + b) * (c / d) 的值是 90
a + (b * c) / d 的值是 50
相关推荐
搬砖的小码农_Sky1 小时前
C语言:数组
c语言·数据结构
ahadee5 小时前
蓝桥杯每日真题 - 第19天
c语言·vscode·算法·蓝桥杯
Theliars5 小时前
C语言之字符串
c语言·开发语言
Reese_Cool6 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
搬砖的小码农_Sky6 小时前
C语言:结构体
c语言·数据结构
平头哥在等你8 小时前
求一个3*3矩阵对角线元素之和
c语言·算法·矩阵
尹蓝锐9 小时前
C语言-11-18笔记
c语言
ahadee9 小时前
蓝桥杯每日真题 - 第18天
c语言·vscode·算法·蓝桥杯
就爱六点起9 小时前
C/C++ 中的类型转换方式
c语言·开发语言·c++
猫猫的小茶馆9 小时前
【C语言】指针常量和常量指针
linux·c语言·开发语言·嵌入式软件