【C语言初阶】万字解析,带你0基础快速入门C语言(下) 2

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【C语言初阶】万字解析,带你0基础快速入门C语言(下)

十二.操作符

4cb123c49a974bd385ab4e4351c73421.png


先大概给大家看看有哪几种,具体用法后面会有博客细讲的

十三.常见关键字

C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。

auto break case char const continue default do double else enum

extern float for goto if int long register return short signed

sizeof static struct switch typedef union unsigned void volatile while


选几个比较有用的讲讲,其他的后面有博客会讲的


1.typedef

typedef 顾名思义是类型定义,这里应该理解为类型重命名。

typedef的重命名其实和人一样,你可以把它理解为人的小名。比如有一个人叫张三,那么从小家里人可能叫他小三,但是这两种叫法的含义是一样的。

e64a9ab6df0640f5bc3d37bb68b96401.jpg

举例说明一下:

//将unsigned int 重命名为uint, 所以uint也是一个类型名
typedef unsigned int uint;
int main()
{
  //观察num1和num2,这两个变量的类型是一样的
  unsigned int num1 = 0;
  uint num2 = 0;
  return 0;
  }

typedef的使用目的往往是使我们在编写代码时更加方便,如上面代码,写出uint是不是简单多了?

2.关键字static

在C语言中:static是用来修饰变量和函数的

1. 修饰局部变量—称为静态局部变量

2. 修饰全局变量—称为静态全局变量

3. 修饰函数—称为静态函数

修饰局部变量

//代码1
#include <stdio.h>
void test()
{
  int i = 0;
  i++;
  printf("%d ", i);
}
int main()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    test();
  }
  return 0;
}
//代码2
#include <stdio.h>
void test()
{
  //static修饰局部变量
  static int i = 0;
  i++;
  printf("%d ", i);
}
int main()
{
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    test();
  }
  return 0;
}

让我们来对比一下代码1和2的运行结果b93f1057ed1b48bca5a1cc2925de8b1d.png

feeba94d57e3458cbfa4b21350099ad7.png


注意:

这里主函数中的i并没有传进test,它的目的只是让test执行十次。

代码1打印10个1的原因:

当打印完test中的i时,i由于是局部变量直接被销毁,再下一次执行test时又重新被初始化为0.

结论:

static修饰局部变量改变了变量的生命周期

让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。


修饰全局变量

int year = 2023;
注意这里的两个year未放在同一个源文件中
int main()
{
  extern year;//表明变量或者函数是定义在其他其他文件中的
  printf("%d ", year);
  return 0;
}

f608cbe7261e4e179c4ca6ea86dc079b.png

同样能运行,但当我们用static修饰一下

d5e9de7574504fceaa03621b05236233.png

结论:

一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。


修饰函数

与修饰全局变量一样

一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。

这里不再缀叙

十四.#define 定义常量和宏

- define翻译为中文就是定义,在这里我们的#define就是给xxxxx下定义的意思。


define定义标识符常量

>#定义   标识符  内容
>#define name  stuff

如下代码

//define定义标识符常量
#define MAX 1000
int main()
{
  int a = MAX;
  printf("%d", a);
  return 0;
}

d7680f49843f4de4b8302f450bda7e82.png


也有类似typedef的用法

#define x int//用x这个名字代替int
x main()
{
  x m = 0;
  printf("%d", m);
  return 0;
}

fdf4f54d35174440911e302a023485ab.png


是不是很神奇呢?

define定义宏

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏 (define macro)


宏的知识是在C语言进阶中的,我们后面也会讲到,这里只是认识它一下。

举个例子:

#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
  int sum = ADD(2, 3);
  printf("sum = %d\n", sum);
  sum = 10*ADD(2, 3);
  printf("sum = %d\n", sum);
  return 0;
}

4d6d805833c74e6ab7e29458836704fc.png


使用起来和函数差不多,但是却比函数看着更加简洁

十五.指针

接下来就是重中之重的指针啦,对于很多学过的人来说,指针是最令人头疼的。由于指针的内容繁且多,所以…(你应该知道我要说什么吧)。

本篇只讲下基础的指针,剩下的内容放在初阶指针以及进阶指针中。

俗话说基础不牢地动山摇,因此这里也要好好看并理解哦!

1.内存及指针定义

讲指针前我们得先知道内存是什么


内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的

所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节

为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址

2dd38a309c3742e3b7a7e1779dcdaf84.png


在C语言中,我们把这个地址就叫我们的指针

有些人可能会问了,这个地址是哪来的,又是怎么编号的呢?该不会是我胡诌的吧?

接下来咱们就讲讲

地址与地址编号的由来

在计算机上,有地址线,其中电线的高低电平的信号,转换为数字信号:1/0

在32(64)位机器,上面有32(64)根地址线

bf623e603ec44a1390b24de90f73e63d.png

二进制,由于有32根地址线,所以一共有2的32次方个字节的空间,也就产生了这么多的编号。1f320629a2ac4140a095a39c63dcf714.png


这就是地址以及其编号的由来

变量在内存中的存储

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。

#include <stdio.h>
int main()
{
  int num = 0;
  &num;//取出num的地址
  //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
  printf("%p\n", &num);//打印地址,%p是以地址的形式打印
  return 0;
}

154fff060aae49c5afe344b8a9e22600.png


35d5890d5abf4726946d752441bc7646.png


那变量的地址如何存储,需要定义指针变量。

2.指针变量

  • 指针变量的意思就是一个存放指针(即地址)的变量
#include <stdio.h>
int main()
{
  int num = 0;
  int* pa = &num;把取到的num的地址放到一个指针变量pa里
  printf("%d", *pa);
  return 0;
}

指针变量的应用

#include <stdio.h>
int main()
{
  int num = 0;
  int* pa = &num;把取到的num的地址放到一个指针变量pa里
  printf("%d", *pa);
  return 0;
}

7a153bc0ebdc4666b9147d92755d2926.png


可见num和*pa两者的结果相同

我们也能通过*pa改变num的值

cd8499a4af504d7294edef9fed9c2ad0.png


3.指针变量的大小

上面我们在内存中讲了内存空间的大小,空间有多大自然就有多大的地址,也就是有多大的指针。

用代码测试一下:

#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
  printf("%d\n", sizeof(char *));
  printf("%d\n", sizeof(short *));
  printf("%d\n", sizeof(int *));
  printf("%d\n", sizeof(double *));
  return 0;
}

cacb5cc06e2e498ca5c24e6df18d1f8a.png


我的电脑是64位平台,因此指针的大小为8个字节

总结:

32位平台下地址是32个bit位(即4个字节)

64位平台下地址是64个bit位(即8个字节)


十六.结构体

该说恭喜还是总算到了最后一章了呢?结构体的知识对于初学者来说也比较难懂,如果这里讲的太深,对于初学者来言,很容易直接从C语言入门到入土,所以咱们这里也还是只简单介绍一下,等之后有了更多的知识后我会写专门的博客来攻克它。


结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。

这里只能使用结构体来描述了。

代码如下

struct stu
{
  char name[10];//名字
  int age;//年龄
  char sex[5];//性别
  char id[20];//学号
};
int main()
{
  struct stu s = { "张三",20,"男","211540239" };
  //其中"."为结构成员访问操作符
  printf("%s %d %s %s\n", s.name, s.age, s.sex, s.id);
  struct stu* ps = &s;//把s的地址存放在结构体指针ps里,通过地址指向s中的值
  //->操作符
  printf("name = %s age = %d sex = %s id = %s\n", ps ->name, ps->age, ps->sex, ps -> id);
}

7a7f5e26365441cb96fd15773dee4ae6.png


总结

如果你有耐心能从上篇开始看到这里,那么我相信此刻你一定对C语言有了一个新的认识。

正如我在文章中一直提到的,以上的部分只是基础的介绍,如果你感兴趣的话,后面还会有每一部分的具体介绍博客和C语言进阶的知识。让我们一起努力,共同进步。去实现自己的梦想与抱负吧!!


以上就是今天要将的所有内容了,如果有任何疑问欢迎在评论区提出或者私信我。

写一篇这么长又这么系统的博客真的很艰难,其中我查阅了大量的资料以及自己上手写了数千行代码,博客中出现的所有解释用的图片也都是我手绘的。

制作不易,如果你觉得对你有所帮助的话,请三连支持一下这个努力的新人博主吧。

cbf5ff92cbc44bcba7de2cecf50d0246.gif

目录
相关文章
|
2月前
|
存储 C语言 C++
【c语言】运算符汇总(万字解析)
今天博主跟大家分享了c语言中各种操作符的功能、使用方法以及优先级和结合性,并且与大家深入探讨了表达式求值的两个重要规则--算数转换和整形提升。学习这些知识对我们的C语言和C++学习都有着极大的帮助。
146 2
|
1月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
156 14
|
1月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
55 8
|
1月前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
582 6
|
1月前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
50 5
|
1月前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
48 5
|
1月前
|
安全 搜索推荐 Unix
【C语言】《回调函数》详细解析
回调函数是指一个通过函数指针调用的函数。它允许将一个函数作为参数传递给另一个函数,并在特定事件发生时执行。这种技术使得编程更加灵活,可以动态决定在何时调用哪个函数。
56 1
|
5天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
42 23
|
5天前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
29 15
|
5天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
41 24

推荐镜像

更多