【C语言】初识C语言(回忆重制版)

前言

        本篇目的是个人重构C语言的知识点框架,方便后期查找与使用,也欢迎大家在评论区指出文章中的错误。

操作环境:Visual Studio 2022 版本

注意:在使用VS2019及以上的编译器在使用 scanf() 的时候均会报错,可以在开始写代码之前在第一行写下以下代码,编译器就不会报错了。

#define _CRT_SECURE_NO_WARNINGS

文章目录

目录

前言

文章目录

1 C语言是什么?

2 第一个C语言程序

2.1 输出 “Hello World!”        

2.2 代码解释

2.3 生成结果 

2.4 关于中文问题

3 数据类型

3.1常见数据类型

3.2 常见数据类型的使用

3.3 计算常见数据类型的大小

4 常量与变量

4.1变量的分类

总结 

4.2变量的使用

4.3 变量的作用域和生命周期

作用域

生命周期

4.4常量 

5 字符串

5.1 字符串简介 

5.2 字符串的使用 

5.3 字符串长度 

6 转义字符

6.1 转义字符简介

6.2 转义字符初识

6.3 转义字符

6.4转义字符的使用

7 注释

7.1 写注释很重要 

7.2 注释风格 

8 选择语句

8.1if-else语句 

示例 

8.2 switch语句

示例1

示例2

示例3 

 9 循环语句

9.1 for 语句 

9.2 while语句 

9.3 do…while语句 

10 函数

10.1 函数是什么

10.2 库函数 

10.3 自定义函数

10.4 自定义函数基本要素

示例一

示例二

11 数组

11.1 数组定义 

11.2 数组的下标

11.3 数组的使用

11.4 注意事项

12 操作符

13 关键字

13.1 常见关键字

13.2 关键字typedef

13.3 关键字static

14 #define 定义常量和宏

15 指针

15.1 内存

15.1.1 取出变量地址 

15.1.2 存储地址

15.1.3 指针的使用

15.2 指针变量的大小 

16 结构体

16.1 定义结构体

16.2 结构体的使用

17 结语​​​​​​​​​​​​​​


1 C语言是什么?

        C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇贝尔电话实验室设计开发了 C 语言。

        尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
        C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。其编译器主要有Clang、GCC(目前大部分配置VScode的常用编译器)、WIN-TC、SUBLIME、MSVC(目前VS2022所使用的编译器)、Turbo C等。


2 第一个C语言程序

2.1 输出 “Hello World!”        

打开编译器,创建好项目,输入以下代码并运行(快捷键F5)。

#include <stdio.h>
int main()
{
    printf("Hello World\n");
    return 0;
}

2.2 代码解释

  • #include 是一个预处理命令,用来引入头文件。
  • stdio.h 是一个头文件 (标准输入输出头文件) 。
  • main() 函数是程序的入口,所有的 C 语言程序都需要包含 main() 函数,一个工程中 main() 函数有且仅有一个。
  • 代码从 main() 函数开始执行。
  • printf() 用于格式化输出到屏幕。 当编译器遇到 printf() 函数时,如果没有找到 stdio.h 头文件,会发生编译错误。printf() 函数在 "stdio.h" 头文件中声明。
  • return 0; 语句用于表示退出程序。

详细请看:printf的常规用法

2.3 生成结果 

        在编译并运行完成之后会在弹出的运行框里看见生成的结果(如下图所示)。 

2.4 关于中文问题

       其实在这里比较推荐在 printf() 函数里输出英文,因为有的人同时使用两种不同的编译器,所以在VS2022上面所输入的中文可能在另一个编译器上会出现乱码(如下图所示)。考虑到是在学习过程中,使用中文的现象是十分正常的且普遍的。所以需要选择好一个固定的编译器进行学习 ,以避免造成不必要的麻烦。

使用 VS2022 打开源码时,中文正常显示

使用  VC code 打开源码时,中文部分出现乱码

3 数据类型

3.1常见数据类型

常见数据类型

int整形
long长整型
long long更长的整形
short短整型
char字符数据类型
float单精度浮点数
double双精度浮点数

        不过值得注意的是,C语言中没有字符串类型 string (C++中才有)!C语言需要使用数组来存储字符串。

        之所以有这么多的数据类型是为了满足各种各样的数据类型的需求。常见的主要有三大类数据:一、整型。二、字符型。三、浮点型。其实C语言当中还有其他类型的数据类型,这里不一一例举。

3.2 常见数据类型的使用

下面的代码展示了一些基础常用的数据类型的声明方法。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	//整型
	int age = 20;
	//短整型
	short num = 10;
	//long 
	//long long

	//字符类型
	char ch = 'a';

	//单精度浮点型
	float weight = 55.5;
	//双精度浮点型
	double d = 0.0;

	return 0;
}

3.3 计算常见数据类型的大小

        接下来开始计算每一个数据类型占据多大的空间。其中数字大小表示各种数据类型的空间大小,单位为字节(byte)。

#include<stdio.h>
int main()
{
	//printf("%d\n", 100);//打印一个整数 - %d
	//sizeof - 关键字 - 操作符 - 计算类型或者变量所占空间的大小

	printf("整型:%d\n", sizeof(int));
	printf("短整型:%d\n", sizeof(short));
	printf("长整型:%d\n", sizeof(long));
	printf("超长整型:%d\n", sizeof(long long));
	printf("字符型:%d\n", sizeof(char));
	printf("单精度浮点型:%d\n", sizeof(float));
	printf("双精度浮点型:%d\n", sizeof(double));

	return 0;
}
运行结果

4 常量与变量

在编写程序的过程当中,既有固定不变的值,也有需要改变的值。

  • 不会改变的值姑且把它认定为常量。
  • 会改变的值也暂时把它认定为变量。

4.1变量的分类

变量有两个分类:

  • 局部变量
  • 全局变量

接下来通过以下代码来了解两者的不同。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int global = 2022;//全局变量

int main()
{
	int local = 2021;//局部变量

	printf("local = %d\n", local);
	printf("global = %d\n", global);

	int global = 2023;//局部变量

	printf("global = %d\n", global);
	return 0;
}
运行结果

总结 

 当局部变量和全局变量同名的时候,局部变量优先使用。

4.2变量的使用

         通过变量的操作我们可以初步实现一个简单的加法操作。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	//定义三个数
	int num1 = 0;
	int num2 = 0;
	int sum = 0;

	printf("输入两个操作数:>");
	scanf("%d %d", &num1, &num2);

	sum = num1 + num2;
	printf("sum = %d\n", sum);
	return 0;
}

4.3 变量的作用域和生命周期

作用域

        作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。

  1.  局部变量的作用域是变量所在的局部范围。
  2.  全局变量的作用域是整个工程。

生命周期

        变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段

  1.  局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
  2.  全局变量的生命周期是:整个程序的生命周期。

        简单来说作用域就是在形如 函数名 () { … } 的函数的 { … } 中。

        生命周期就是函数什么时候使用结束,以为例子,当主函数 main () { … } 走完时,即整个程序周期结束。

4.4常量 

C语言中的常量和变量的定义的形式有所差异。
C语言中的常量分为以下以下几种:

  • 字面常量
  • const 修饰的常变量
  • #define 定义的标识符常量
  • 枚举常量
#define _CRT_SECURE_NO_WARNINGS
#define MAX 100
#include <stdio.h>
//举例
enum Sex
{
	MALE,
	FEMALE,
	SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
	//字面常量演示
	3.14;//字面常量
	1000;//字面常量
	//const 修饰的常变量
	const float pai = 3.14f; //这里的pai是const修饰的常变量
	//pai = 5.14;//是不能直接修改的!
	printf("%f\n", pai);
	//#define的标识符常量 演示

	printf("max = %d\n", MAX);
	//枚举常量演示
	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);
	//注:枚举常量的默认是从0开始,依次向下递增1的

	return 0;
}
运行结果

        关于变量和常量就介绍这么多了。


5 字符串

5.1 字符串简介 

"Hello World!\n";

        这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。

5.2 字符串的使用 

        因为C语言中没有字符串类型,所以需要使用数组来存储字符串内容。下面是三种字符串的使用方法。 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	char arr1[] = "Hello";
	char arr2[] = { 'H', 'e', 'l' , 'l' , 'o' };
	char arr3[] = { 'H', 'e', 'l' , 'l' , 'o', '\0' };
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	return 0;
}

        注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。

5.3 字符串长度 

        想要知道有效字符串的长度需要用到以下函数:

        strlen(): 从使用的该函数的地方开始计数字符串,直到遇见 ‘\0’ 为止。使用时需引用头文件

#include<string.h>

        sizeof(): 计算字符串字节数,需要经过特殊处理,处理步骤如下。

    int array1[]={1,2,3,4,5,6,7,8,9,10};
	int num1 = sizeof(array1) / sizeof(array1[0]);

打开监视器窗口,可以更直接了当的看见数组内部的存储情况。

监视器窗口

        但是,如果计算该字符串长度的时候发现arr2[]的大小与其他两个数组的大小是不一样的!

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "Hello";
	char arr2[] = { 'H', 'e', 'l' , 'l' , 'o' };
	char arr3[] = { 'H', 'e', 'l' , 'l' , 'o', '\0' };
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);

	//求一下字符串的长度
	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	printf("%d\n", strlen(arr3));
	return 0;
}


6 转义字符

6.1 转义字符简介

        转义字符顾名思义就是转变意思。

6.2 转义字符初识

        当需要在运行框里打印一连串带标点符号时,需要使用转义字符才能打印相应的字符。否则将如下图所示。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	printf("c:\code\test.c\n");
	return 0;
}
错误示范

6.3 转义字符

转义字符释义
\?在书写连续多个问号时使用,防止他们被解析成三字母词
\'用于表示字符常量'
\“用于表示一个字符串内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a警告字符,蜂鸣
\b退格符
\f换页符
\n换行
\r回车
\t水平制表符
\v垂直制表符
\dddddd表示1~3个八进制的数字。 如: \130 X
\xdd

dd表示2个十六进制数字。 如: \x30 0

6.4转义字符的使用

         转义字符除了上述的这些,还有转义ASCll值,其中对该字符串计算的时候,一个转义字符会被算成一个字符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	//错误示范
	printf("c:\code\test.c\n");
	//正确示范
	printf("c:\\code\\test.c");	

	//换行符
	printf("\n");
	//打印斜杠
	printf("\\\n");
	//打印引号
	printf("\'\n");
	printf("\"\n");
	//水平制表符
	printf("A\ta\n");
	//警告字符
	printf("\a");

	return 0;
}


7 注释

7.1 写注释很重要 

写注释很重要!写注释很重要!写注释很重要!

        重要的事情说三遍! 写注释的好处不仅是方便后期维护,而且可以极大地提高代码阅读性,甚至可以帮助写代码的时候思路清晰不偏离。因此,在写之前,写时,写后都要及时补上注释。

#include<stdio.h>

//int main()
//{
//  /*
//	//int a = 10; //C++注释风格
//	/*
//	int b = 0;
//	*/   
//	//C语言的注释风格 - 不支持嵌套注释
//  */
//	return 0;
//}

7.2 注释风格 

        C语言有两种注释风格:一种是C++注释风格“//” 另一种就是C语言的注释风格 /* */ 。

虽然C++注释风格需要在每行之前打上“//”,但是好在 VS2022 编译器能帮助我们快速注释。

第一按钮注释,第二个撤回

        C语言的注释风格则不支持嵌套注释,因此常见的就是C++风格的注释,C语言风格则用在注释一大段解释的时候就排上用场了。


8 选择语句

        在进行一个流程运算的时候,会有一个判断输入或者上一步得到的值该何去何从,因此这个环节就暂时称它为判断选择环节,满足不同的条件有着不同的运行过程。

        C语言中有两种选择语句:

  • if-else语句:if( ){ … } else { … }
  • switch语句:switch( ){ case: …  }

8.1if-else语句 

        当逻辑判断产生两种结果时,一个结果为真(想要的结果),另一个结果为假(不想要的结果),这个时候就可以使用 if语句 来实现这个简单的逻辑。大致用法如下:

if 语句的使用

        if( 判断条件 )

                {

                        //如果判断结果为真就执行该区域中的语句

                        执行语句1;

                        ……

                } 

        else

                {

                        //如果判断结果为假就执行该区域中的语句

                        执行语句2;

                        ……

                }

示例 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int coding = 0;
	printf("今天你学习了吗?(选择1 or 0):>");
	scanf("%d", &coding);
	if (coding == 1)
	{
		printf("真棒!\n");
	}
	else
	{
		printf("加油!\n");
	}
	return 0;
}

8.2 switch语句

        当逻辑判断产生多种结果时,这时使用 if-else语句 显然是非常繁杂的,如果使用 switch语句 就会使整个代码更加简洁且易于理解。大致用法如下:

switch语句的使用

        switch( 传入结果 )

                {

                        case 结果1: 执行语句1;//当传入的结果与结果相等时,执行执行语句1

                                break;//当执行语句1结束时会通过break跳出该选择语句

                                             //如果没有break,会按顺序执行每一个case中的执行语句,

                                               直到遇到break为止。

                        case 结果2:……

                                ……

                        default://如果传入结果没有等于以上结果则执行该结果的执行语句 

                                执行语句n;

                                break;

                }

示例1

给下面输入一个数字判断是星期几。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//switch语句
int main()
{
	int date;
	scanf("%d", &date);
	//判断今天星期几
	switch (date)
	{
	case 1:
		printf("星期一\n");
		break;
	case 2:
		printf("星期二\n");
		break;
	case 3:
		printf("星期三\n");
		break;
	case 4:
		printf("星期四\n");
		break;
	case 5:
		printf("星期五\n");
		break;
	case 6:
		printf("星期六\n");
		break;
	case 7:
		printf("星期日\n");
		break;
	default:
		printf("输入错误!\n");
		break;
	}

	return 0;
}
结果一
结果二

        从上面我们可以看到,输入数字几程序就会给出相应的星期几,这里是有 break 结束的结果。 

示例2

接下来判断输入的数是工作日还是休息日。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//switch语句
int main()
{
	int date;
	scanf("%d", &date);
	//判断今天星期几
	switch (date)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("工作日\n");
		break;
	case 6:
	case 7:
		printf("休息日\n");
		break;
	default:
		printf("输入错误!\n");
		break;
	}

	return 0;
}

示例3 

当输入的值不在 case 预设中时,会得到 default 执行语句 中的结果。


 9 循环语句

        有的事情需要重复的反复的做,使用循环语句可以帮助我们快速完成。

在C语言中有三种循环语句:

  • while
  • for
  • do…whlie

 循环能用来做什么呢?可以按顺序输出一连串有序数字,也还可以快速输入试错。 

9.1 for 语句 

for 语句的使用

        for( 循环条件1;循环条件2;循环条件3 ) // 这三个循环条件需要依据情况而定

                {

                        执行语句;

                }

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//for语句
int main()
{
	int a = 1;
	int i = 0;
	int j = 0;
	//打印10个1
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a);
	}
	printf("\n");
	//打印1~10
	for (j = 1; j <= 10; j++)
	{
		printf("%d ", j);
	}
	return 0;
}
打印10个1和打印1~10

9.2 while语句 

         while 虽然括号中只能存放一个循环条件语句,但也需要一些其他循环条件的辅助,在下面的代码中已经给标注出来了。

while语句的使用

        while( 循环条件 )

                {

                        执行语句;

                }

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	int password=0;
	int word = 100;//循环条件1
	printf("请设置三位数的密码:>\n");
	scanf("%d", &password);
	while (word < 1000)//循环条件2
	{
		if (word == password)
		{
			printf("正确密码为:%d\n",word);
		}
		word++;//循环条件3
	}
	return 0;
}

9.3 do…while语句 

do…while 循环是 先执行 再判断 是否满足循环条件的循环语句。

do…while语句的使用

        do{

                        执行语句;

           }while( 循环条件 );

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//do while语句
int main()
{
	int input;
	do {
		printf("0.Epit\n");
		printf("1.Begin\n");
		printf("Please Input:>");
		scanf("%d", &input);
	} while (input);
	return 0;
}


10 函数

10.1 函数是什么

        函数是一组一起执行一个任务的语句。函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。每个 C 程序都至少有一个函数,即主函数 main()。函数又大致分成两类:一类是库函数,另一类是自定义函数

10.2 库函数 

        回顾之前出现的 printf() 它就是一个库函数,它可以将内容按照指定的格式输出。它是一个函数,当我们包含<stdio.h>这个头文件时,就可以调用它了,使用库函数时,必须包含 #include 对应的头文件。除此之外,还有其他的库函数,例如,<string.h>库函数中的函数 strcat() 用来连接两个字符串,函数 strlen() 用来计算字符数的大小等等,还有<math.h>库函数中的sqrt()返回平方根,pow()返回幂次方等等。

10.3 自定义函数

        当代一段完整的代码写完时,在写接下来的代码当中,希望不要重复写解决同一种问题的代码,这个时候就需要使用到我们的函数了。 

10.4 自定义函数基本要素

  • 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void
  • 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
  • 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
  • 函数主体:函数主体包含一组定义函数执行任务的语句。

示例一

首先展示的是一段完整的解决某一问题(实现加法)的代码。 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
示例一结果

示例二

接下来把以上代码给改写成行函数的形式。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int add(int x, int y)
{
	int z = x + y;
	return z;
}

int main()
{
	int num1 = 0;
	int num2 = 0;
	int sum = 0;
	printf("输入两个操作数:>");
	scanf("%d %d", &num1, &num2);
	sum = add(num1, num2);
	printf("sum = %d\n", sum);
	return 0;
}


11 数组

C语言中给了数组的定义:一组相同类型元素的集合

11.1 数组定义 

定义:数据类型 + 数组名 [ 数组大小 ] = { 数组元素1 , …… , 数组元素n };

//定义一个整形数组,最多放10个元素
int arr[10] = {1,2,3,4,5,6,7,8,9,10};

11.2 数组的下标

C语言规定:数组的每个元素都有一个下标,下标是从0开始的
数组可以通过下标来访问的

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
int arr2[10] = {0};

        这连个数组有10个元素,下标的范围是0-9,每个下标里面都有相应的值。

监视窗口

11.3 数组的使用

        想要对数组里面进行操作,就得需要使用到循环来帮助我们进行操作。

        无论是打印还是输出,都需要找到相应的下标,像操作变量那样,对其进行操作。 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//打印
void Print(int arr[])
{
	int i = 0;
	for (i = 0; i < 10; i++){
		printf("%d ", arr[i]);
	}
}

int main()
{
	//数组的定义
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	//输入
	printf("请输入10个数字:>");
	for (int i = 0; i < 10; i++){
		scanf("%d", &arr2[i]);
	}
	//打印
	printf("打印arr1:");
	Print(arr1);
	printf("\n");
	printf("打印arr2:");
	Print(arr2);
	return 0;
}
运行结果

11.4 注意事项

        下标不能为正好等于数组大小!否则会数组中会多出一个数组之外的数字。使得到的数组结果不准确。

        如果数组当中不完全初始化,剩余的默认为0 

监视窗口

        在对数组进行赋值时不要忘记加上取地址符 &,否则会出错。


12 操作符

这里仅介绍部分操作符,多的不再讲述,有兴趣可以自己探索!

【C语言】常见的操作符

算术操作符    +         -         *         /         %
移位操作符 >>        <<
位操作符&         ^         |
赋值操作符   =         +=         -=         *=         /=         &=         ^=         |=         >>=         <<=
单目操作符         !      逻辑反操作
        -      负值
        +      正值
        &      取地址
        sizeof    操作数的类型长度(以字节为单位)
        ~      对一个数的二进制按位取反
        --      前置、后置--
        ++      前置、后置++
        *      间接访问操作符(解引用操作符)
        (类型)    强制类型转换
关系操作符        >        大于
        >=      大于等于
        <        小于
        <=      小于等于
        !=       用于测试“不相等”
        ==      用于测试“相等”
逻辑操作符        &&   逻辑与
        ||      逻辑或
条件操作符表达式1 ? 表达式2 : 表达式3
逗号表达式 表达式1, 表达式2, 表达式3, …表达式N
下标引用、函数调用和结构成员   []         ()         .         ->

13 关键字

13.1 常见关键字

C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,在定义的时候不能义他们为名,这样做会造成重命名。
auto          break          case          char          const          continue          default          do double         else          enum         extern         float          for          goto          if        register  int long       return       short          signed      sizeof          static         struct        switch      typedef        union        unsigned      void        volatile          while

13.2 关键字typedef

        关键字 typedef 在C语言中是用来自定义数据类型名称,就像给一种要用类型定义一个新的名字,并且这两个类型是一样的,如以下例子:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

//定义unsigned int这一类型为uint
	typedef unsigned int uint;
int main()
{
	//两种定义的类型都是一样的
	unsigned int num1 = 0;
	uint num2 = 1;
	return 0;
}

13.3 关键字static

        在C语言中:static是用来修饰变量和函数的,它被用来控制变量的存储方式和可见性。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void test()
{
	static int a = 1;
	a++;
	printf("%d ", a);
}

int main()
{
	int i = 0;
	while (i<10)
	{
		test();
		i++;
	}
	return 0;
}
静态局部变量

关于更多 static :【C语言】关键字static进阶讲解


14 #define 定义常量和宏

        #define可以定义一个常量,相当于创建了一个全局常量,并且可以放在数组当中,由其定义宏也可以当作创建了一个函数。

#define _CRT_SECURE_NO_WARNINGS
//define 定义标识符常量
#define num 100
//define 定义宏
#define ADD(x,y) ((x)+(y))

#include<stdio.h>
int main()
{
	//使用define 定义标识符常量
	printf("%d\n", num);
	int n = num;
	printf("%d\n", n);
	int arr[num] = { 0 };
	//使用define 定义宏
	int a = 10, b = 20;
	int c = ADD(a, b);
	printf("%d\n", c);
	return 0;
}


15 指针

15.1 内存

        提到了指针就不得不讲一点内存,因为指针在底层逻辑上就是内存地址的操作。        

        内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
        所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
        为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

        内存的地址是由高到低的方式排序,并且存储的时候是从低位开始向高位存储数据。

图一

15.1.1 取出变量地址 

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

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int num = 10;
	&num;//取出num的地址
	//打印地址,%p是以地址的形式打印
	printf("%p\n", &num);
	return 0;
}

注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)

15.1.2 存储地址

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

        pa是用来存放地址的,在C语言中pa叫是指针变量

int main()
{
	int* pa = &pa;
	return 0;
}

15.1.3 指针的使用

int main()
{
	int a = 10;

	int* pa = &a;

	*pa = 20;//* 解引用操作 | *pa就是通过pa里边的地址,找到a

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

	return 0;
}

监视窗口

         通过图监视窗口可以发现,在程序运行到后半段的时候,随着*pa的改变,a中的值也随之改变。

15.2 指针变量的大小 

        指针变量的大小取决于地址的大小
        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;
}
64位
32位

16 结构体

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
比如描述学生,学生包含: 名字+年龄+性别+学号这几项信息。
这里只能使用结构体来描述了。

16.1 定义结构体

        结构体组成:

        struct 结构体名

        {

                数据类型 成员名;

                ……

        };

struct Stu
{
	char name[20];//成员变量
	int age;
	double score;
};

16.2 结构体的使用

        首先要创建结构体和进行初始化。

        struct 结构体名 成员名 = { 初始化值…… };

这里的初始化值要与先前创建数组的时候的数据类型相对应。

        输出的时候要先用成员名 . 成员变量

        在使用指针指向成员名的时候,有两种指向成员变量的方法。

        ( *指针名 ) . 成员变量

        指针名 -> 成员变量

int main()
{
	struct Stu s = { "张三", 20, 85.5 };//结构体的创建和初始化
	printf("1: %s %d %lf\n", s.name, s.age, s.score);//结构体变量.成员变量

	struct Stu* ps = &s;
	printf("2: %s %d %lf\n", (*ps).name, (*ps).age, (*ps).score);

	printf("3: %s %d %lf\n", ps->name, ps->age, ps->score);

	return 0;
}

17 结语

        以上就是初识C语言的全部内容了,想要学好编程语言还是得好好敲代码,这种反反复复的练习一定能带来满满的收获。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值