目录
1. 什么是C语言
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易
的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语
言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的
C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超
级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制
定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 [1] 目前2011年12月8
日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标
准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉
字编程。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
2. 第一个C语言程序
代码:
#include<stdio.h>
int main()
{
printf("hello world!\n");
return 0;
}
1.main(主函数)是一个程序的入口,每一个程序都是从main函数开始执行的。在一段代码中有且只有一个main函数。
2.int是一个整型,表示main函数在它运行结束之后会返回一个整型的值。
3.return 0它的意思是返回0,0是一个整数,在main函数结束时被返回,它要做到与前面的int前后呼应。
4.printf是一个库函数,库函数的使用必须包含一个头文件(stdio.h)。
5.stdio.h中stdio是指“standard input & output",即标准输入输出,.h是值header。
3.数据的类型
1.数据的类型
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
注意:在使用float定义时,在数字后面加一个f,否则计算机将默认为double类型。
2.数据类型所占用的内存
代码:
#include <stdio.h>
int main()
{
printf("%d\n", sizeof(char));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(long));
printf("%d\n", sizeof(long long));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));
printf("%d\n", sizeof(long double));
return 0; }
编译器得出的结果:
1
2
4
4
8
4
8
8
1.sizeof:用来计算变量或者使用类型创建的变量的大小,单位是字节。
2.计算机中的单位:
1字节(byte)= 8比特(bit)
1 KB=1 024 B
1MB=1024KB
1GB=1024MB
1TB=1024GB
3.c语言中规定sizeof(long)>=sizeof(int)。
4.%d:打印十进制的整数。
3.类型的使用
char ch = 'w';
int weight = 120;
int salary = 20000;
4.变量、常量
1.定义变量的方法
int age = 150;
float weight = 45.5f;
char ch = 'w';
当一个局部变量不初始化的时候,它的值是随机的。
2.变量的命名
只能由字母(包括大写和小写)、数字和下划线( _ )组成。
不能以数字开头。
长度不能超过63个字符。
变量名中区分大小写的。
变量名不能使用关键字。
3.变量的分类
#include <stdio.h>
int global = 2019;//全局变量
int main()
{
int local = 2018;//局部变量
int global = 2020;//局部变量
printf("global = %d\n", global);
return 0;
}
注意:当全局变量与局部变量名字相同的情况下,局部优先。
global=2020
4.变量的使用
代码:
#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;
}
运行结果:
输入两个操作数:>2 3
sum = 5
1.scanf也是一个库函数,它是由stdio.h包含的一个输入函数。
2.&:取地址符。
5. 变量的作用域和生命周期
1.作用域
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用
的而限定这个名字的可用性的代码范围就是这个名字的作用域。
- 局部变量的作用域是变量所在的局部范围。
- 全局变量的作用域是整个工程。
2.生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期。
代码:
#include<stdio.h>
int main()
{
int a = 100;
{
int b = 200;
printf("%d\n", b);
}
printf("%d\n", b);
return 0;
}
此时运行结果出错:第二个“b":报错未定义的标识符。
6.常量
C语言中的常量分为以下以下几种:
- 字面常量
- const 修饰的常变量
- #define 定义的标识符常量
- 枚举常量
1.字面常量
100;
3.14;
“abcd”;
‘w’;
2.const修饰的常变量
代码:
#include<stdio.h>
int main()
{
const int num = 10;
printf("%d\n", num);
num = 20;
printf("%d\n", num);
return 0;
}
此时代码的运行结果出错,因为const修饰的变量无法被修改
注:但是它依然具有变量的性质
const int num=100;
int arr[num]={0};
此时程序运行会报错“应输入常量表达式”。
注:
上面例子上的 num被称为 const 修饰的常变量, const 修饰的常变量在C语言中只是在语法层面限制了
变量 num 不能直接被改变,但是 num本质上还是一个变量的,所以叫常变量。
3.#define定义的标识符常量
#define MAX 100
#include<stdio.h>
int main()
{
printf("%d",MAX);//100
MAX=200;//修改MAX的值
//error
}
4.枚举常量
枚举-------一一列举
例:性别:男、女、保密
血型:
三原色:R、G、B
enum Sex
{
MALE,
FEMALE,
SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
enum Sex s=MALE;
printf("%d\n",MALE);//0
printf("%d\n",FEMALE);//1
printf("%d\n",SECRET);//2
return 0;
}
5.字符串+转义字符+注释
1.字符串
字符:‘a’ ‘#’
字符串:“abc" “hello world”
这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a','b','c' };
char arr3[] = { 'a','b','c','\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;
}
打印结果
abc
abc烫烫烫烫蘟bc
abc
3
15 //随机值
3
因为arr2中没有’\0’,因此要让它停下来需要向后寻找,所以产生随机值。
注:
1.strlen的作用是计算字符串在内存中所占的空间大小,需要#include<string.h>这个头文件去包含。
2.%s打印字符串,%c打印字符。
2.转义字符
转义字符 | 释义 |
---|---|
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\’ | 用于表示字符常量’ |
\“ | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1-3个八进制的数字。 |
\xdd | dd表示2个16进制的数字。 |
#include <stdio.h>
int main()
{
printf("c:\tode\test.c\n");
return 0;
}
c: ode est.c
"\t"就是转义字符
printf("(hehe\?\?)"); //打印(hehe??)
printf("%c",'\''); //打印'
printf("%s","\""); //打印"
printf("c:\\test\\104\\test.c"); //打印c:\test\104\test.c
printf("\a\a\a\a"); //电脑蜂鸣
printf("%c\n",'\130'); //8进制的130转化成的10进制数88作为ASCII值所对应的符号:X
printf("%c\n",'\x30'); //16进制的30转化成的10进制数48作为ASCII值所对应的符号:0
例:计算题
#include<stdio.h>
#include<string.h>
int main()
{
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
14
//c : \t est \62 8 \t est . c
3.注释
注释有两种风格:
C语言风格的注释 /xxxxxx/
缺陷:不能嵌套注释
C++风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
- 代码中有不需要的代码可以直接删除,也可以注释掉
- 代码中有些代码比较难懂,可以加一下注释文字
6.选择语句(只说if)
代码:
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
if(coding == 1)
{
printf("坚持,你会有好offer\n");
}
else
{
printf("放弃,回家卖红薯\n");
}
return 0;
}
运行结果:
你会去敲代码吗?(选择1 or 0):>1
坚持,你会有好offer
你会去敲代码吗?(选择1 or 0):>0
放弃,回家卖红薯
7.循环语句(只说while)
//while循环的实例
#include <stdio.h>
int main()
{
printf("加入比特\n");
int line = 0;
while(line<=20000)
{
line++;
printf("我要继续努力敲代码\n");
}
if(line>20000)
printf("好offer\n");
return 0;
}
8.函数
1.函数的特点就是简化代码,代码复用。
2.C语言中,把一些独立的功能封装成一个独立的函数
#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;
}
上述代码,写成函数如下:
#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;
}
1.正常情况下,将函数放到主函数之前,一定要放在主函数之后的话,要先在主函数之前进行函数声明(以上图代码为例,将函数代码放在主函数之后,并在主函数之前加 int Add(int x, int y); 进行函数声明)
2.函数中int Add(int x, int y)中:Add为函数名;int x, int y为函数的形式参数;int为返回类型与后面的return z中z的类型相对应;函数中用大括号括起来的内容叫函数体。
下图:
9.数组
1.数组的定义
1.定义一个整型数组,最多存放十个元素。
int arr[10]={1,2,3,4,5,6,7,8,9,10}
2.数组的初始化
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int arr[10]={1,2,3};//只初始化前三个,其他的都为0.
int arr[]={1,2,3};
int arr[];//error
3.数组的下标
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问的。
例如:
使用下标来访问
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",arr[5]}
6
4.数组的使用
代码:
#include <stdio.h>
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 2 3 4 5 6 7 8 9 10
10.操作符(简单介绍)
C语言包含了非常丰富的操作符,所以有人说”C语言是非常灵活的“,甚至直接可以操作内存数据,可以直接操作二进制位。
1.算数操作符
+ - * / %
/:除
%:取余
1.取余
注:只能作用在整数中,不能用于浮点数(小数)。
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("%d %d", a % b, b % a);
return 0;
}
5 6 //输入
5 1 //输出
2.除法
当除号左右都是整数时,结果只能是整数。
当有小数时,结果才是小数
a=5/2; //2
a=5.0/2; //2.5
2.移位移动符
>> //右移 << //左移
移位操作符作用于一个二进制数
3.位操作符
& ^ |
&:按位与(对应二进制:有一个0就是0,全1就是1.)
^:按位异或(对应二进制:相同为0,相异为1)
|:按位或(对应二进制:有一个1就是1,全0就是0.)
4.赋值操作符
= += -= *= /= &= ^= |= >>= <<=
就是简化写法:
a=a+4;
a+=4;//实现的效果相同
5.单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
– 前置、后置–
++ 前置、后置++
* 间接访问操作符(解引用操作符) (类型) 强制类型转换
1.逻辑反操作
int a=1;
printf("%d\n",!a);//输出0
int a=0;
printf("%d\n",!a);//输出1
2.sizeof操作符
int a=10;
int arr[10];
int arr2[]={0,1,2,3};
printf("%d\n",sizeof(a));//4
printf("%d\n",sizeof(int));//4
printf("%d\n",sizeof(arr));//40
printf("%d\n",sizeof(arr[0]));//4
printf("%d\n",sizeof(arr)/sizeof(arr[0]));//10 可以用来计算数组元素个数
printf("%d\n",sizeof(arr2)/sizeof(arr2[0]));//4 4个元素
3.++、–操作符
> 前置++:++n 先++,再使用
> 后置++:n++ 先使用,再++
> 前置--:--n 先--,再使用
> 后置--:n-- 先使用,再--
int a=10;
int b=++a;
printf("%d\n",a,b);//11 11
int a=10;
int b=a++;
printf("%d\n",a,b); //11 10
int a=10;
int b=--a;
printf("%d\n",a,b);//9 9
int a=10;
int b=a--;
printf("%d\n",a,b);//9 10
4.强制类型转换
int n=(int)9.19;
printf("%d",n);//9
6.关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
7.逻辑操作符
&& 逻辑与
|| 逻辑或
逻辑与:两个条件同时满足输出
逻辑或:两个条件只要满足一个就输出
8.条件操作符
exp1 ? exp2 : exp3
功能解释:
表达式1的结果为真,表达式2算,表达式3不算,表达式2的结果是整个表达式的结果。
表达式1的结果为假,表达式2不算,表达式3算,表达式3的结果是整个表达式的结果。
int a = 0;
int b = 0;
int m = 0;
scanf("%d %d", &a, &b);
// //if (a > b)
// // m = a;
// //else
// // m = b;
//
m = (a > b ? a : b);//和上面的作用一致
printf("%d\n", m);
return 0;
9.逗号表达式
exp1, exp2, exp3, …expN
从左向右依次计算,但是最终的结果是最后一项。
int main()
{
int a = 3;
int b = 0;
int c = 4;
int d = (a=b-3,b=a+c,c=a-b,a=c+3);
//a=-3 b=1 c=-4 a=-1
printf("%d\n", d);//d=-1
return 0;
}
10.下标引用、函数调用和结构成员
[] () . ->
11.常见的关键字
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.关键字是系统定义的。
2.关键字不能做变量名。
auto:是用来定义自动变量(自动创建,自动回收)
int main()
{
auto int a=0;
return 0;
}
循环语句:
break:终止(在while,for,do while中使用,也可以在switch中使用)
continue:继续
do:do while
while
选择语句:
case:在switch中使用
default:在switch中使用
switch
if、else
数据类型:
char short int long float double
类型中使用
unsigned(无符号) signed
const:常属性,用于修饰变量或修饰指针。
自定义类型
enum:枚举
struct:结构体
union:联合体
extern:用于声明外部符号
goto:用于分支和循环
register:寄存器
typedef:类型重定义
return:是返回,在函数中使用
void:用于函数返回类型,函数参数,修饰指针。
static:静态的
1.typedef
typedef unsigned int unit;
int main()
{
unsigned int num1 = 10;
unit num2 = 20;
return 0;
}
2.static
在C语言中:
static是用来修饰变量和函数的
- 修饰局部变量-称为静态局部变量
- 修饰全局变量-称为静态全局变量
- 修饰函数-称为静态函数
1.修饰局部变量
//代码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 1 1 1 1 1 1 1 1 1 //10个1
代码二结果:1 2 3 4 5 6 7 8 9 10
结论:
static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
static修饰局部变量的时候,改变了变量的存储类型,普通的局部变量是储存在栈区,被static修饰的变量储存在静态区,储存在静态区的变量,出作用域不会销毁,依然存在,所以变量的生命周期就是程序的生命周期,程序结束,静态变量才会回收空间。
2.修饰全局变量
一个全局变量在整个工程的其他文件内部能被使用,是因为全局变量具有外部链接属性,当一个全局变量被static修饰的时候,这个变量的外部链接属性就变成了内部链接属性,使得这个全局变量只能在自己所在的源文件内部使用,其他文件不能再使用,给我们的感觉是作用域变小了。即static修饰全局变量,使全局变量失去了外部属性,作用域变小,生命周期不变!(仍是整个工程),存储位置不变(在静态区)。
3.修饰函数
结论:static修饰函数的时候,函数本来也是具有外部属性的,被static修饰的时候,就变成了内部链接属性。这个函数只能在自己所在的源文件内部使用,不能在其他文件内部使用。给我们的感觉是改变了作用域。
12.#define定义常量和宏
//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x)+(y))
13.指针
1.内存
1.内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
2.所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
3.为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地
址。
在计算机中,存储地址使用16进制。
一、变量是创建在内存中的,每一个内存单元都有地址。
#include<stdio.h>
int main()
{
int a = 100;//申请四个字节的空间
printf("%p\n", &a);
return 0;
}
注:%p是用来打印地址的
内存调试
运行结果
00CFFC80
二、定义指针变量
#include<stdio.h?
int main()
{
int a=10;
char ch='e';
int *p=&a; //p就是指针变量
char *pc=&ch;
printf("%p\n",&p);
printf("%p\n",&pc);
return 0;
}
注:
- p中存储的是a的首地址
- 指针变量存储的就是地址
三、指针变量的作用
int main()
{
int a = 10;
int* pa = &a;//& 取地址操作符
*pa = 20;//* 解引用操作
printf("%d\n", a);//输出20
return 0;
}
注:
*为解引用操作符或间接访问操作符,作用是通过这个符号找到一个变量的地址,进而进行修改。
2.指针变量的大小
32位机器 - 一个地址是32个二进制位,存储需要32个bit位的空间,所32位机器上,指针变量的大小是4个字节
64位机器 - 一个地址是64个二进制位,存储需要64个bit位的空间,所64位机器上,指针变量的大小是8个字节
一、32位机器
int main()
{
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(double*));
return 0;
}
4
4
4
4
4
4
二、64位机器
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;
}
8
8
8
8
8
8
注:%zu是sizeof专用的打印符号
14.结构体
有些复杂对象只能用结构体表示
一、结构体类型及使用
例:
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);
//访问规则:结构体变量.结构体成员
运行结果:
二、指针变量使用->操作符和.操作符的区别
#include<stdio.h>
struct Stu
{
char name[20];
int age;
char sex[5];
char id[12];
};
void print(struct Stu* ps)
{
printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).id);
//*指针变量.结构体成员
printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->id);
//结构体指针->结构体成员
}
int main()
{
struct Stu s = { 0 };
//输入
scanf("%s %s %s %d", s.name, s.sex, s.id, &(s.age));
print(&s);
return 0;
}
zhang nan 20220718 18 //输入
zhang 18 nan 20220718 //输出
zhang 18 nan 20220718
总结
以上就是初识C语言的全部内容,只是简单的过了一遍。
希望大家多多支持!!!