提示:本文篇幅较长,耐心看完一定能有所收获,适用于C语言期末考复习,或者刚入门的新手
本篇文章基本介绍了C语言的基础知识,可以让你对C语言有一个大概的了解。
对于每个知识点,都只是简单识记,后续会分开讲解
C语言是一门通用计算机编程语言,广泛应用于底层开发,拥有着良好的跨平台特性,即以一个标准规格写出的C语言程序能够在许多电脑平台上运行。为了各厂商的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法。C语言是一门面向过程的计算机编程语言,常见编译器有GCC、MSVC、Clang、Turbo C等
代码如下(示例):
#include //#include为引用操作stdio.h为文件名,本行表示引用头文件
int main() //main意为主函数,是整个程序的入口,程序从这里进入并开始执行,int表示
//main函数的返回值为整形
{
printf("Hello World!\n");//printf函数表示打印,此函数包含在stdio.h的头文件中,先进行了头文
//件的包含,printf函数才能顺利打印\n表示换行符。
return 0; //return 0表示返回值为0,程序正常结束
}
运行结果 : Hello World!
相信大家在自己在屏幕上打印出Hello World!之后,一定对C语言中各种数据的类型非常感兴趣。
char //字符数据类型 例: char = 'w';
short //短整型 完整写法为(short int)
int //整型
long //长整型 (long int)
long long //更长的整型(long long int)
float //单精度浮点数 定义小数
double //双精度浮点数 定义小数,精度比float大
#include
int main()
{ //运行结果 此处的sizeof函数计算数据的大小,单位字节
printf("%d\n", sizeof(char)); //1
printf("%d\n", sizeof(short)); //2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long)); //8
printf("%d\n", sizeof(float)); //4
printf("%d\n", sizeof(double)); //8
printf("%d\n", sizeof(long double));//8
return 0;
}
生活中有些值是可以改变的,如年龄、体重、选择题答案,这其中年龄一般用体重表示,体重一般用小数表示。所以需要不同的变量类型来定义
int age = 20;//定义整形变量
float weight = 50.5;//定义浮点型变量,也可以用double,精度更高
char answer='A';//定义字符型变量
·全局变量
·局部变量
#include
int global = 2022;//全局变量(定义在主函数外)
int main()
{
int local = 2023;//局部变量(定义在主函数内,仅在主函数内有效)
//下面定义的global会不会有问题?
int global = 2024;//局部变量
printf("global = %d\n", global);
return 0;
}
输出结果:global = 2024
结论:全局变量和局部变量可同名,局部变量优先使用,成为局部优先。故结果为2024。
#include
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);//此处scanf函数为输入函数,%d为输入的数据类型,&为 取地址 操作符
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
//输入:10 20
//输出结果为:sum = 30
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用
的
而限定这个名字的可用性的代码范围就是这个名字的作用域。
生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1.局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。
C语言中的常量分类:
·字面常量
·const修饰的常变量
·#define定义的标识符常量
·枚举常量
#include
//枚举常量(通常用全部大写字母表示)
enum Sex
{
MALE,
FEMALE,
SECRET
};
int main()
{
3.14;//字面常量
1000;//字面常量
const float pi=3.14f;//const修饰的常变量pi
pi=5.14;//这里的pi经过const修饰是不能直接修改的!
//const 修饰的常变量在C语言的语法层面受到限制,变量pi本身不能直接被改变,
//但pi本质上还是一个变量,所以叫常变量
#define MAX 100 //#define的标识符常量
printf("max = %d\n",max);//此处打印结果为100
//枚举常量演示
printf("%d\n",MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//枚举常量的默认是从0开始,依次向下递增1的
return 0;//结束主函数
}
"hello world\n"
这种由双引号引起来的一串字符称为字符串字面值,简称字符串
注意:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
举例,理解 \0 的意义
#include
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作为结尾,而printf函数只有在遇到\0时才会停止打印,而在hello存储的内存中,之后的部分是随机存储的,并不知道何时会遇到\0所以会打印出一堆乱码
首先看一些基本的转义字符
\? 在书写连续多个问号时使用,防止他们被解析成三字母词
\' 用于表示字符常量'
\“ 用于表示一个字符串内部的双引号
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。 如: \130 X
\xdd dd表示2个十六进制数字。 如: \x30 0
转义字符的简单应用
#include
int main()
{
//在屏幕上打印一个单引号'
printf("%c\n", '\'');
//在屏幕上打印一个字符串,字符串的内容是一个双引号“
printf("%s\n", "\"");
return 0;
}
#include
int Add(int x, int y)
{
return x+y;
}
/*注释方法一
int Sub(int x, int y)
{
return x-y;
}
*/
int main()
{
//注释方法二
//int a = 10;
//调用Add函数,完成加法
printf("%d\n", Add(1, 2));
return 0;
}
注意在使用/* */ 进行注释时,不能嵌套注释
#include
int main()
{
int learn = 0;
scanf("%d",&learn);
if(learn == 1)//两个等于号代表判断,一个等于号代表赋值
{
printf("获得好成绩\n");
}
else
{
printf("一事无成\n");
}
return 0;
}
这里的if和else代表了两个分支,如果if后的判断条件成立,则执行if后{}的内容,否则执行else后{}内的内容
·while循环
·for循环
·do…while循环
本篇文章简单介绍一下,后期继续详解
#include
int main()
{
int line = 0;
//在屏幕上输出从0到30000
//while循环
while(line<=30000)
{
printf("%d\n",line);
line++;
}
//for循环
for(int i=0;i<=30000;i++)
{
printf("%d\n",i);
}
//do while循环
int i=0;
do
{
printf("%d\n",i);
i++;
}while(i<=30000);
return 0;
}
#include
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;
}
上述代码,写成函数如下:
#include
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;
}
函数的特点:简化代码,灵活复用
int arr[10]={1,2,3,4,5,6,7,8,9,10};//定义一个整形数组
//数组的下标 0 1 2 3 4 5 6 7 8 9
数组的下标从0开始,数组可以通过下标来访问
#include
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
以上代码打印出数字1-10
简单介绍
//算数操作符
+ - * / %
//移位操作符
>> <<
//位操作符
& ^ |
//赋值操作符
= += -= *= /= %= &= ^= |= >>= <<=
//单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换 //如(int)、(double)
//关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
//逻辑操作符
&& 逻辑与
|| 逻辑或
//条件操作符(三目操作符)
e1?e2:e3
//逗号表达式
e1,e2,e2,...,eN
下标引用、函数调用和结构成员
[] () . ->
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
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;
}
在C语言中:
static是用来修饰变量和函数的
//代码1
#include
void test()
{
int i = 0;
i++;//整形的i每次函数结束就销毁了,每次进入都重新创建变量i,所以每次打印1
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
//代码2
#include
void test()
{
//static修饰局部变量
static int i = 0;
i++; //打印出1 2 3 4 5 6 7 8 9 10,因为static修饰后,变量i储存在静态区
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
对比代码1和代码2的效果理解static修饰局部变量的意义。
结论:
static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x)+(y))
#include
int main()
{
int sum = ADD(2, 3);
printf("sum = %d\n", sum);
sum = 10*ADD(2, 3);
printf("sum = %d\n", sum);
return 0;
}
注意:这里的定义的常量和宏仅仅是替换,如果没有写成((x)+(y))的形式,可能会产生副作用。如果没有最外面的大括号,10ADD(2,3)会变成102+3
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
#include
int main()
{
int num = 10;
#//取出num的地址
//注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n", &num);//打印地址,%p是以地址的形式打印
return 0;
}
地址的储存需要定义指针变量
int num = 10;
int *p;//p为一个整形指针变量
p = #
指针的使用实例
#include
int main()
{
int num = 10;
int *p = #
*p = 20;//这里*为解引用符,对num的地址进行解引用,找到了num存储的10,修改为20
return 0;
}
#include
//指针变量的大小取决于地址的大小
//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;
}
在C语言中,如果要描述复杂类型
如学生,包含:名字、年龄、性别、学号
此时需要用到结构体来描述
struct Stu
{
char name[20];//名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
};
结构体的初始化
//打印结构体信息
struct Stu s = {"张三", 20, "男", "20180101"};
//.为结构成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
//->通过指针直接访问,相当于先解引用,再用.访问
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps-
>id);
以上就是今天讲的所有内容,简单粗略介绍了C语言中涉及的主要知识点,这里并没有对每个知识点进行细讲,在接下来的文章中将会进行详解,作者只是个菜鸟,如有错误,希望大家多多在评论区中指正。