IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 1. 初识C语言 -> 正文阅读

[C++知识库]1. 初识C语言

初识C语言

  • 什么是C语言
  • 第一个C语言程序
  • 数据类型
  • 变量、常量
  • 字符串+转义字符+注释
  • 选择语句
  • 循环语句
  • 函数
  • 数组
  • 操作符
  • 常见关键字
  • define 定义常量和宏
  • 指针
  • 结构体

什么是C语言

C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产

生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。

编译器:MSVC(VS2019)、GCC

第一个C语言程序

创建工程步骤:

  1. 创建新项目

  2. 创建源文件 test.c–源文件 test.h–头文件

  3. 写代码

#include <stdio.h>
int main()
{
    printf("hello bit\n");//printf - 库函数 - 打印函数 - 输出函数
    printf("he he\n");
    return 0;
}
//注释:
#include <stdio.h>//包含头文件,声明引用,printf、scanf
                  //stdio - 标准输入输出
int main()//函数返回类型-函数名-函数参数  
{
	return 0;//主函数调用完返回一个整数(return 0)
}
//主函数是程序的入口-从main函数第一行开始执行
//有且仅有一个主函数

操作快捷键:

运行代码:

Ctrl + F5

[Fn] + Ctrl + F5

调试代码:

F10–逐步执行

//主函数其他写法1:
 int main(void)//--void - 明确的告诉我们,main函数不需要参数(main函数本质上可以有参数的)
{                        
	return 0;
}
//2:
 int main(int argc, char* argv[])//明确的告诉我们,main函数有两个参数
{

	return 0;
}
//过时写法:
void main()
{

}

数据类型

char        //字符数据类型
short       //短整型
int         //整形
long        //长整型
long long   //更长的整形
float       //单精度浮点数
double      //双精度浮点数
//C语言有没有字符串类型?
  • 类型的使用:
//存在这么多的类型,其实是为了更加丰富的表达生活中的各种值
#include <stdio.h>
int main()
{
	int age = 10;        //描述年龄 - int类型创建age变量存放,赋值10
	int price = 50;      //描述价格 - int类型创建price变量存放,赋值50
	double weight = 55.5;//double - 双精度浮点型 - 小数点可以浮动

	return 0;
}
  • 每种类型的大小是多少?
#include <stdio.h>
int main()
{
    //如何计算一个类型创建的变量所占空间的大小(byte)呢?
	printf("%d\n", sizeof(char));      //计算char类型创建的变量所占空间 - 1byte
	printf("%d\n", sizeof(short));     //2byte
	printf("%d\n", sizeof(int));       //4byte          
	printf("%d\n", sizeof(long));      //4byte      
	printf("%d\n", sizeof(long long)); //8byte          
	printf("%d\n", sizeof(float));     //4byte       
	printf("%d\n", sizeof(double));    //8byte       

	return 0;
}

//注:C语言标准规定:
sizeof(long long) > sizeof(long) > sizeof(int)

image-20210811203127735

不同格式打印的结果:

//%d - 打印格式-整数
//%c - 打印字符
#include <stdio.h>
int main()
{
	char ch = 'e';     //-单引号引起来的是字符-创建char类型的变量ch,存字符e
	printf("%c\n", ch);//e
	printf("%d\n", ch);//101

	return 0;
}

//键盘 - abcdef!@#$字符
//计算机存储 - 二进制
//存'a'? 
//存'#'?
//字符编号存储 - ASCII码

变量、常量

生活中的有些值是不变的(比如:圆周率,性别(?),身份证号码,血型等等)

有些值是可变的(比如:年龄,体重,薪资)。

不变的值,C语言中用常量的概念来表示;变的值,C语言中用变量来表示。

定义变量的方法

#include <stdio.h>
int main()
{
	float weight;
	char sex = 'm';
	short age = 10;//age是变量
	age = 11;
	printf("%d\n", age);

	return 0;
}

变量的分类

  • 局部变量
  • 全局变量
#include <stdio.h>

int g = 100;//全局变量

void test()
{
	int b = 1000;//局部变量
}

int main()
{
	int a = 10;//局部变量

	return 0;
}
#include <stdio.h>
int a = 100;//全局变量
 
int main()
{
	int a = 10;//局部变量
	printf("%d\n", a);//? - 10
	return 0;
}

image-20210811205905028

局部变量和全局变量可以同名

局部变量和全局变量同名,局部优先,但不建议相同

局部变量和全局变量相互独立,互不影响

#include <stdio.h>
int a = 100;          //全局变量
 void test()          //函数-打印全局变量
{
	printf("%d\n", a);//100
}
int main()
{
	int a = 10;       //局部变量

	printf("%d\n", a);//局部优先 - 10
	a = 20;
	test();           //调用函数
	printf("%d\n", a);//局部优先 - 20
						
	return 0;
}

image-20210812193014219

变量的使用

//例子:2个整数相加
#include <stdio.h>
int main()
{
	//定义变量
	int num1 = 0;
	int num2 = 0;
	//输入
	scanf("%d%d", &num1, &num2);//取地址-输入10,20 - 或"%d%d"、"%d %d",必须输入格式一致
	//做加法
	int sum = num1 + num2;//存和
	//输出
	printf("%d\n", sum);

	return 0;
}

image-20210811210402444

’This function or varible may be unsafe’解决方法:

  • 代码开头加入一句话:#define _CRT_SECURE_NO_WARNINGS 1

  • 找到newc++file.cpp,加入一句话:#define _CRT_SECURE_NO_WARNINGS 1

    1. 以管理员权限打开VS2019

    2. 打开文件(ctrl+O)

      路径:"E:\Program Files (x86)\Microsoft Visual

      Studio\2019\Community\Common7\IDE\VC\VCProjectItems\newc++file.cpp"

    3. 添加:#define _CRT_SECURE_NO_WARNINGS 1并保存

变量的作用域和生命周期

作用域

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

围就是这个名字的作用域。

  1. 局部变量的作用域是变量所在的局部范围。

image-20210812193752982

image-20210812193945540

  1. 全局变量的作用域是整个工程(跨文件使用也可以)

image-20210812194112454

//在外部文件test2.c定义全局变量 - int g_val = 2021;
//须声明外部变量
extern int g_val;
#include <stdio.h>
int main()
{
	printf("%d\n", g_val);

	return 0;
}

生命周期

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

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

常量

C语言中的常量分为以下以下几种:

  1. 字面常量
#include <stdio.h>
int main()
{
	3.14;//浮点型的字面常量
	100;
	float a = 3.14;
	return 0;
}
  1. const 修饰的常变量

常属性 - 一个变量不能被改变的属性

#include <stdio.h>
int main()
{
	int a = 100;      //局部变量
	a = 200;
	printf("%d\n", a);//200

	const int b = 100;
	b = 200;
	printf("%d\n", b);//err

	return 0;
}

image-20210812200608971

const修饰的常变量依旧是变量,不是常量,只是具有常属性,不能被修改而已

#include <stdio.h>
int main()
{
	const int n = 100;
	int arr[n] = {0};//创建数组,数组元素个数必须是常量

	return 0;
}

image-20210812201051291

  1. #define 定义的标识符常量
#include <stdio.h>

#define MAX 100
int main()
{
	int a = MAX;
	int arr[MAX] = {0};

	printf("a = %d\n", a);
 
	//MAX = 200;//err,不能修改!

	return 0;
}

image-20210812201910083

  1. 枚举常量
  • 枚举 - 一一列举,例:性别、三原色
  • 创建完枚举类型后,打印时,默认0、1、2···向下递增。可赋初值
  • 枚举常量不可改
#include <stdio.h>
//枚举类型
enum Sex
{
	//枚举常量 - 枚举的可能取值
	MALE=3,    //赋初值
	FEMALE=7,
	SECRET    //运行结果3、7、8
};

int main()
{
	//enum Sex s = SECRET;

	printf("%d\n", MALE);  //打印时,默认0、1、2···向下递增
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);

	//MALE = 4;//err,枚举常量不可改
	return 0;
}

字符串+转义字符+注释

字符串

char - 字符类型;
"hello world\n"  //字符串字面值

 //有没有听过字符串类型?---没有

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

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

‘a’ 单引号引起 - 字符

“abcdef” 双引号引起 - 字符串

‘ab’ 胡写!

字符串初始化

#include <stdio.h>

int main()
{
	char ch1[10] = "abcdef";//用字符串初始化数组,有7个元素,包含'\0'

    char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f'};//有6个元素
	return 0;
}

image-20210812211200106

\0 作为结束标志的体现

#include <stdio.h>

int main()
{
	char ch1[10] = "abcdef";//用字符串初始化数组,有7个元素
	printf("%s\n", ch1);

	char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f' };//有6个元素
	printf("%s\n", ch2);
	return 0;
}

image-20210812211345086

image-20210812211643741

’\0’在求字符串长度时的作用

\0:打印时作为字符串结束标志;

求长度时不包含\0,不算在长度内

//strlen是库函数 - 求字符串长度
//strlen需要头文件 - #include <string.h>
#include <stdio.h>
#include <string.h>
int main()
{
	char ch1[10] = "abcdef";
	printf("%d\n", strlen(ch1));//计算字符串长度

	char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
	printf("%d\n", strlen(ch2));
	return 0;
}

image-20210812212255599

image-20210812212334381

image-20210812213125670

转义字符

假如要在屏幕上打印一个目录: c:\code\test.c

#include <stdio.h>
int main()
{
 printf("c:\code\test.c\n");//\t - 是一个转义字符
    return 0;
}

实际结果:

image-20210812213703227

转义字符 - 把原来的意思转变

例:n:字符 \n:换行符

image-20210812214007308

转义字符释义
?在书写连续多个问号时使用,防止他们被解析成三字母词

三字母词;
??) --> ]
??( --> [

printf("%s\n", "????)");//若支持三字母词,则打印效果:??]
//为避免:printf("%s\n", "??\?\?)");
//\?-避免误解析成三字母词
转义字符释义
\’用于表示字符常量’
\’’用于表示一个字符串内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符。
\t水平制表符
printf("%c", 'a');-打印字符a
printf("%c", '\'');-打印'
printf("%s\n", "\"");-字符串打印内容为"
printf("%s\n", "c:\\test\\test.c");

image-20210812224046636

image-20210812231808179

转义字符释义
\dddddd表示1~3个八进制的数字。 如: \130 X
\xdddd表示2个十六进制数字。 如: \x30 0

\ddd - ddd的8进制数字转换成10进制后的值,作为ASCII值对应的字符

\xdd - dd的8进制数字转换成10进制后的值,作为ASCII值对应的字符

#include <stdio.h>
int main()
{
	printf("%c\n", '\065');//8进制:065 -->10进制:53
	printf("%c\n", '5');   //打印字符5
    printf("%c\n", '\x51');//16进制:51 -->10进制:81 -->ASCII值:Q
    
	return 0;
}

image-20210813100448136

image-20210813100657246

练习:

//程序输出什么?
#include <stdio.h>
int main()
{
    printf("%d\n", strlen("abcdef"));            //6
    // \32被解析成一个转义字符
    printf("%d\n", strlen("c:\test\328\test.c"));//14,8不在8进制内
    return 0;
}

image-20210813101524482

注释

  1. 代码中有不需要的代码可以直接删除,也可以注释掉
  2. 代码中有些代码比较难懂,可以加一下注释文字

注释有两种风格:

  • C语言风格的注释 /*xxxxxx*/

    • 缺陷:不能嵌套注释
  • C++风格的注释 //xxxxxxxx

    • 可以注释一行也可以注释多行

选择语句

image-20210813104340080

//选择语句
int main()
{
	int input = 0;
	printf("加入比特\n");
	printf("要好好敲代码吗(1/0)?");
	scanf("%d", &input);

	if (input == 1)
	{
		printf("好offer\n");
	}
	else
	{
		printf("卖红薯\n");
	}

	return 0;
}

循环语句

有些事必须一直做,比如大家,日复一日的学习。

image-20210813104834775

C语言中如何实现循环呢?

  • while语句
  • for语句(后期分析)
  • do … while语句(后期分析)
//记录敲代码20000行
#include <stdio.h> 
int main()
{
	int line = 0;
	printf("加入比特\n");

	while (line<20000)
	{
		printf("敲代码:%d\n", line);
		line++;
	}

	if(line >= 20000)
		printf("好offer\n");

	return 0;
}

image-20210813105343843


函数

//函数:计算两个数的和
//盘子 = 张三(20元, 蛋炒饭
#include <stdio.h>
int Add(int x, int y)
{
	int z = 0;//z作为变量名,可以任取
	z = x + y;
	return z;
}

int main()
{
	int num1 = 0;
	int num2 = 0;
	int sum = 0;
	//输入
	scanf("%d %d", &num1, &num2);

	//计算
	//sum = num1 + num2;
	sum = Add(num1, num2);//Add函数
	
	//输出
	printf("%d\n", sum);

	return 0;
}

image-20210813110420907


数组

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

数组定义

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//赋初值,定义一个整形数组,最多放10个元素
char ch[5] = {'a', 'b', 'c'};//字符数组

image-20210813111512337

下标默认从0开始,更好访问元素

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//[10]-创建数组时指定数组大小,元素个数为10
printf("%d ", arr[5]);                 //5是下标,打印数组内第6个元素 - 6

数组使用

//正序打印数组全部元素
#include <stdio.h>
int main()
{ 
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 
	int i = 0;//下标0-9
	while (i < 10)
	{
		printf("%d ", arr[i]);//数组内下标为i的元素
		i++;
	}
	return 0;
}

image-20210813112313092


操作符

简单介绍,后续详解。

算术操作符

+  -  *  /  %
//整数除法和浮点数除法
#include <stdio.h>
int main()
{
	int a = 5 / 2;
	printf("%d\n", a);

	float b = 5 / 2.0;
	printf("%f\n", b);
	return 0;
}

image-20210813133315671

//% - 取模(余)得到的是整除之后的余数
#include <stdio.h>
 int main()
{           
	int a = 7 % 2;//商3 ... 余1
	printf("%d\n", a);

	return 0;
}

移位操作符 - 作用于二进制位

>>  <<
//移位操作符:左移、右移
#include <stdio.h>
 int main()
{
	int a = 6;
	int b = a << 1;//a左移1位
	printf("%d\n", b);//12
	printf("%d\n", a);//?  a的结果不变,还是6

	return 0;
}

image-20210813134557014

image-20210813134704037

位操作符

&  ^  |
//& - 按位与 - 有0为0
#include <stdio.h>
int main()
{
	int a = 3;                                   	
	int b = 5;  
    
	int c = a & b;
	printf("%d\n", c);//结果为7


	return 0;
}

image-20210813151832793

//| - 按位或 - 有1为1
#include <stdio.h>
int main()
{
	int a = 3;                                   	
	int b = 5;                                      
	                                                
	int c = a | b;                
	printf("%d\n", c);//7
	return 0;
}

image-20210813152108645

 //^ - 按位异或 - 相同为0,相异为1
#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;

	int c = a ^ b;
	printf("%d\n", c);//6
	return 0;
}

image-20210813152639544

赋值操作符

=  +=  -=  *=  /=  &=  ^=   |=    >>=   <<=
//赋值操作符
#include <stdio.h>
int main()
{
	int a = 10;//创建变量a,并且初始化为10,不算赋值!

	a = 20;//赋值

	a = a + 10;//复合赋值-两种写法
	a += 10;

	a = a - 8;
	a -= 8;

	a = a >> 1;
	a >>= 1;

	return 0;
}

单目操作符

a+b:a和b是+的两个操作数 —> +:双目操作符

!    逻辑反操作
//真和假
//非0就是真   5 - 真
//0就是假     0 - 假
#include <stdio.h>
int main()
{
	int a = 10;//真
	printf("%d\n", !a);//0
	
    int a = 0;
	printf("%d\n", !a);//1

    //写法:
 	int a = 10;
	if (a)//a为真,进入if语句
	{

	}

	if (!a)//a为假,进入if语句
	{

	}
	return 0;
}
-    负值
+    正值
#include <stdio.h>
int main()
{
	int a = 10;
	int b = -a;//负值
	int c = +a;//

	return 0;
}
&            取地址
sizeof()     操作数的类型长度(以字节为单位)
#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", sizeof(a));//4
	printf("%d\n", sizeof(int));//4

	return 0;
}
~        对一个数的二进制按位取反
#include <stdio.h>
int main()
{
	int a = 0;

	printf("%d\n", ~a);//-1

	return 0;
}
//00000000000000000000000000000000
//11111111111111111111111111111111 - 补码(~a后的结果)
//11111111111111111111111111111110 - 反码
//10000000000000000000000000000001 - 原码
  1. 整数在内存中存储的时候,存储是二进制

  2. 一个整数的二进制表示有3种形式:

  • 原码
  • 反码
  • 补码
  1. 正的整数:原码、反码、补码相同

? 负的整数:原码、反码、补码需要计算

  1. 有符号的整数,最高位是0,表示正数

? 最高位是1,表示负数

  1. 内存中存储整数的时候,存储的是二进制的补码,计算的时候采用也是补码

例:

int a = 1;//4个字节-32bit
//00000000000000000000000000000001 - 原码
//00000000000000000000000000000001 - 反码
//00000000000000000000000000000001 - 补码

int a = -1;
//10000000000000000000000000000001 - 原码
//11111111111111111111111111111110 - 反码 (原码的符号位不变,其他位按位取反得到反码)
//11111111111111111111111111111111 - 补码 (反码的二进制序列+1就是补码)
++      前置、后置++
--      前置、后置-- 
#include <stdio.h>
int main()
{
    int a = 2;
    
	//a = a + 1;
	//a += 1;
	//a++;
    printf("%d\n", a);//结果为3,以上三种写法一样

	return 0;
}

#include <stdio.h>
int main()
{
    int a = 2;

    //前置++:先++,后使用
    int c = ++a;
    printf("%d\n", c);//3
	printf("%d\n", a);//3

    //后置++:先使用,后++
    int c = a++;
    printf("%d\n", c);//2
    printf("%d\n", a);//3
    
    //前置--:先--,后使用
    int c = --a;
    printf("%d\n", c);//1
	printf("%d\n", a);//1

    //后置--:先使用,后--
	int c = a--;
	printf("c = %d\n", c);//2
	printf("a = %d\n", a);//1
 
 return 0;
}

注:

//错误的代码,不同平台,结果不同
int main()
{
	int a = 1;
	int b = (++a) + (++a) + (++a);
	printf("b = %d\n", b);

	return 0;
}
 
//不可取的代码
int main()
{
	int a = 10;
	printf("%d %d\n", --a, --a);//?

	return 0;
}
*           间接访问操作符(解引用操作符)
(类型)      强制类型转换
//强制类型转换,尽量避免
#include <stdio.h>
int main()
{

	int a = (int)3.14;//int占4字节;单独3.14为double类型,占8字节,精度更高
	printf("%d\n", a);

	return 0;
}

image-20210813163936151

关系操作符

=
<
<=
!=       用于测试“不相等”
==       用于测试“相等”

逻辑操作符

&&    逻辑与 - '并且'
||    逻辑或 - '或者'
#include <stdio.h>
int main()
{
	int a = 3;
	int b = 4;
	//如果a==3 并且 b==4,打印哈哈;如果有一个条件不满足,则打印不了
	if ((a == 3) && (b == 4))
	{
		printf("哈哈\n");
	}
 
	//如果a==3 或者 b==4,打印呵呵;有一个条件满足即可,两个条件都满足更佳
	if ((a == 3) || (b == 4))//加括号避免优先级冲突
	{
		printf("呵呵\n");
	}
	return 0;
}

条件操作符(三目操作符)

exp1 ? exp2 : exp3
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 0;
	if (a == 5)
	{
		b = -6;
	}
	else
	{
		b = 6;
	}//常见写法
    
    //三个操作数,简化代码
	b = ((a == 5) ? (-6) : (6) );//运用'条件操作符'写法
	return 0;
}

逗号表达式

exp1, exp2, exp3, …expN
//,  - 逗号表达式
//逗号表达式会从左向右依次计算;整个逗号表达式的结果是最后一个表达式的结果
#include <stdio.h>
int main()
{
	int a = 0;
	int b = 3;
	int c = -1;
    int d = (a = b - 5, b = a + c, c = a + b, c -= 5);

	//a=-2
    //b=-3         
    //c=-5        
    //c=-10
	
	printf("%d\n", d);//-10

	return 0;
}

下标引用、函数调用和结构成员

[]   ()   .   ->
//[]下标引用操作符
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//下标0~9
    arr[9];                                //访问第10个元素,[] - 下标引用操作符

	return 0;
}
  • arr、9分别是两个操作数
  • int arr[10]中的[]是定义数组大小的写法
//() - 函数调用操作符
int main()
{
	printf("hehe\n");//()函数调用操作符
 	return 0;
}

//() - 函数调用操作符
int Add(int x, int y)
{
	return x + y;
}

void test()
{

}
 
int main()
{
	test();
 	int ret = Add(3, 5); //()函数调用操作符

	return 0;
}

函数调用操作符的操作数不固定:

  • Add(3, 5) - 3个操作数:Add、3、5
  • printf(“hehe\n”) - 2个操作数:printf、""内的字符串
  • 函数不需要传参,函数名本身是操作数

常见关键字

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
int main()
{
	//关键字auto省略 
	int a = 10;//局部变量 -也叫自动变量:进出大括号,自动创建自动销毁

	return 0;
}

break - 停止,中断 - 用于循环,switch语句

switch-case

const - 常属性
 
continue - 继续 - 用于循环
 
do - 常用于do-while语句
for
while

if else
goto
 
enum - 枚举关键字
struct - 结构体
  
extern - 声明外部符号
 
register - 寄存器    

return - 返回 - 函数

char
double
float
int
long
short
signed - 有符号的,应用于正负数
unsigned - 无符号的
  
sizeof   

static - 静态的 

struct - 结构体  
 
typedef -类型重定义
 
union - 联合体(共用体)  
 
void -空,无
volatile - Linux - 易变的

关键字C语言内置,不能拿自己的定义的符号名和关键字冲突!

register

#include <stdio.h>
int main()
{
	//建议作用!建议把100存放在寄存器中,编译器最终决定
	register int num = 100;//100放到num,放到寄存器中
    //&num;//err,取地址是取内存地址,不能取寄存器地址
						  
	return 0;
}

关键字 typedef

typedef:类型定义,这里理解为类型重命名

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

关键字static

在C语言中:

static是用来修饰变量和函数的

  1. 修饰局部变量-静态局部变量
  2. 修饰全局变量-静态全局变量
  3. 修饰函数-静态函数
  • 修饰局部变量
//每次进入函数,创建a变量,赋值1,++变2,打印,出函数变量销毁
void test()
{
	int a = 1;
	a++;//2
	printf("%d ", a);//10个2
}

#include <stdio.h>
int main()
{
	int i = 0;
	while (i < 10)
	{
		test();//调用10次test();
		i++;
	}
	return 0;
}

image-20210813201231045

//若用static修饰局部变量
//出作用域变量a不会销毁
//static改变了变量的生命周期 - 延长生命周期 - 不影响作用域
void test()
{
	static int a = 1;
	a++;
	printf("%d ", a);//2~11
}

#include <stdio.h>
int main()
{
	int i = 0;
	while (i < 10)
	{
		test();//调用10次();
		i++;
	}

	return 0;
}

image-20210813201456749

结论:

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

  • 修饰全局变量

全局变量-extern可用-链接

image-20210813205038194

static修饰全局变量

image-20210813205236224

//add.c
static int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0;
}

结论:

  • 默认一个全局变量具有【外部】链接属性
  • 而全局变量被static修饰,使全局变量的外部链接属性变成内部链接属性
  • 此时该全局变量只能在本源文件内部使用,其他源文件无法链接到,也无法使用
  • 修饰函数

image-20210813210226088

static修饰函数

image-20210813210443104

结论:

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

  • static将函数外部链接属性变为内部链接属性


#define 定义常量和宏

  1. #define定义常量
#include <stdio.h>
#define NUM 100 //#define定义常量

int main()
{
	printf("%d\n", NUM);

	return 0;
}
  1. #define定义宏
//求X、Y 较大值
#include <stdio.h>
#define MAX(X,Y)  (X>Y?X:Y)
//宏名 - 宏参数 - 宏体

int main()
{
	 int a = 10;
	 int b = 20;

	 int c = MAX(a, b);//工作原理:替换 - int c = (a > b ? a : b);

	 printf("%d\n", c);//20

	 return 0;
}

指针

内存

  • 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址
  • 为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节

image-20210815213602779

变量都有地址,取出变量地址如下:

#include <stdio.h>
int main()
{
	int a = 10;//向内存申请4个字节的空间,空间名为a,里边存放10
 	printf("%p\n", &a);//打印地址,%p--以地址的形式打印
 	
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVxIMT1r-1629038565284)(E:\比特就业课\C_初阶\1.初识C语言\初识C语言.assets\image-20210815204633677.png)]

image-20210815204904944

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

地址可以很好找到内存空间,故也称指针

当指针存到某变量中去,也称该变量为指针变量

int num = 10;
int *p;//p为一个整形指针变量
p = &num;
#include <stdio.h>
int main()
{
	int a = 10;//向内存申请4个字节的空间,空间名为a,里边存放10
 	
	int * pa = &a;//pa存放a的地址,是一个存放地址的变量,被称为指针变量
                  //* - 代表pa是指针变量
                  //int - pa指向的对象a是int类型

	return 0;
}

image-20210815210349096

指针变量的解引用操作

两大操作符

  • &

pa是指针变量,即变量本身

*pa是指针pa指向的对象,即a

指针变量

  1. 把地址放进去
  2. 通过地址找到所指向的空间
#include <stdio.h>

int main()
{
	int a = 10;//向内存申请4个字节的空间,空间名为a,里边存放10
	int * pa = &a;//pa存放a的地址,是一个存放地址的变量,被称为指针变量
	* pa = 20;//通过pa里存放的地址找到所指向的空间a,并赋新值20    
              
	printf("%d\n", a);//20
	
    printf("%p\n", *pa)//以地址形式(16进制)打印a的内容  00000014 - 10进制:20
 
	return 0;
}

image-20210815213104160

image-20210815211650812

以整形指针举例,可以推广到其他类型,如:

#include <stdio.h>
int main()
{
	char ch = 'w';
	char* pc = &ch;
    *pc = 'q';
    printf("%c\n", ch);
    return 0;
}

注意:

int a = 10;//int - 4byte  [][][][]
char* p = &a;//应是int*,否则类型不兼容

指针变量的大小

指针变量存放的是地址,地址的大小是4byte,则指针变量也是4byte

  • 32位机器(x86) - 32根地址线 - 32bit - 4byte
  • 64位机器(x64) - 64根地址线 - 64bit - 8byte
#include <stdio.h>
int main()
{
	printf("%zu\n", sizeof(char*));
	printf("%zu\n", sizeof(short*));
	printf("%zu\n", sizeof(int*));
	printf("%zu\n", sizeof(long*));
	printf("%zu\n", sizeof(float*));
	printf("%zu\n", sizeof(double*));

	return 0;
}

image-20210815214541869

int main()
{
	char c = 'w';
	char* pc = &c;
	printf("%d\n", sizeof(pc));//4
	return 0;
}

结论:

地址的大小与是什么类型的地址无关!


结构体

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

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

  • 声明结构体类型
  • 结构体的初始化
  • 访问结构体
    • . 为结构成员访问操作符:结构体变量.成员名
    • 指针操作:-> - 结构体指针->成员名
//声明一个学生类型
struct Stu
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]//学号
};

struct Book
{
	
	char name[20];//成员变量
	int price;
	char author[20];
};

//结构体初始化
int main()
{ 
	//创建的结构体变量
	struct Student s1 = {"张三", 20, "男", "20200506"};
	struct Student s2 = {"lisi", 30, "女", "20200908"};
	struct Book b1 = { "C语言程序设计", 55, "谭浩强" };

    //打印结构体信息
	printf("名字: %s 年龄: %d 性别: %s 学号: %s\n", s1.name, s1.age, s1.sex, s1.id);
	printf("%s %d %s\n", b1.name, b1.price, b1.author);

	struct Book * pb = &b1;//指针操作
	printf("%s %d %s\n", (*pb).name, (*pb).price, (*pb).author);
	printf("%s %d %s\n", pb->name, pb->price, pb->author);

	return 0;
}

完结撒花。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:33:49  更:2021-08-16 11:35:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:48:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码