前言:
大家好,我是良辰丫,初来乍到,承蒙厚爱。学习了一段时间编程且浅读几本书籍,决定与君共勉,每隔一段时间进行一次总结,充实自己。这篇文章从头到尾简单的带大家梳理一下C语言,让大家对C语言有一定的认识,这样大家在学习C语言的过程中就容易很多了!!!废话不多说,我们开始初识C语言,gogogo!!!
- 计算机行业发展迅速,短短几年时间,各个编程语言成为了热门,C语言,C++,Java,Python等。那么编程语言到底是什么呢?
- 人类有自己的沟通语言,中国人用汉语实现交流沟通,英国人用英语进行交谈。那么如果我们用汉语和一个不会汉语的英国人交流,那肯定达不到效果。
- 与人类类似,计算机也有自己可以直接识别的语言---->机器语言。
- 编程语言(programming language),是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令。在电脑领域已发明了上千不同的编程语言,而且每年仍有新的
编程语言诞生。很多编程语言需要用指令方式说明计算的程序,而有些编程语言则属于声明式编程,说明需要的结果,而不说明如何计算。编程语言的描述一般可以分为语法及语义。语法是说明编程语言中,哪些符号或文字的组合方式是正确的,语义则是对于编程的解释。 目前通用的编程语言有两种形式:汇编语言和高级语言。
如果刚接触编程语言,听不懂很正常,知识需要日积月累,人不是一生下来就会跑的,满怀激情,朝着心中的方向一往直前,最终鲜花会绽放!!!
C++
,Java
等面向对象的编程语言有所不同。#include
int main()
{
printf("hello world\n");
printf("我是叶良辰\n");
//双引号里面的内容为字符串,printf的固定格式
return 0;
}
代码解释:
- 第一行引入输入输出头文件,stdio.h包含了标准输入输出库的信息
举个不太恰当的例子,借用了人家库函数的东西不得向人家打个招呼嘛?这样才显得礼貌- main函数是程序的入口,一个程序中main函数有且仅有一个
一个程序是从main函数开始运行的,没有main函数程序就没有了头绪。- printf是C语言输出语句,把想打印的内容打印到屏幕上
printf是库函数(输出语句),使用需要头文件stdio.h,
输出语句的内容需要用双引号引用(C语言固定格式)- \n表示换行,这是一种转义字符,后续了解
- return 0表示正常结束程序
- 分号表示一句指令结束
数据类型 | 所占字节(32位) | 类型名称 |
---|---|---|
char | 1 | 字符数据类型 |
short | 2 | 短整型 |
int | 4 | 整形 |
long | 4 | 长整型 |
long long | 8 | 更长的整形 |
float | 4 | 单精度浮点数 |
double | 8 | 双精度浮点数 |
//计算各种数据类型的大小
#include
int main()
{
printf("char:%d\n", sizeof(char));
printf("short:%d\n", sizeof(short));
printf("int:%d\n", sizeof(int));
printf("long:%d\n", sizeof(long));
printf("long long:%d\n", sizeof(long long));
printf("float:%d\n", sizeof(float));
printf("double:%d\n", sizeof(double));
return 0;
}
解释:sizeof计算空间大小(单位为字节)
顾名思义变量是可以修改的量,比如商品的价格,可以涨价和掉价,有幅度变化;而常量是固定不可变的量,比如你的出生日期,性别等,这是不可以修改的。
int age = 10;
char f = 'Y' ;
定义变量的格式
数据类型 变量名 = 赋值
命名有一定的规则,由C语言所规定的
注意:命名一定要有意义,让别人有一目了然之感,如下代码
可以让别人很容易看出定义了一个年的变量int year = 0;
#include
int year = 2020;//全局变量
int main()
{
int local_year = 2022;//局部变量
//下面定义的变量有问题吗?是否会有重定义的问题?
int year = 2010;//局部变量
printf("global = %d\n", global);
return 0;
}
总结:
哈哈!上面的局部变量global变量的定义其实没有什么问题的!
当局部变量和全局变量同名的时候,局部变量优先使用
不断学习,注意细节,积累编程思想,不断突破自己
#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;
}
&为取地址符,看到这个,大家又产生一种疑惑了嘛?
printf中引用变量没有使用&,而scanf却使用了,一个大大的问号浮在脑海
scanf是从键盘输入东西,引用&符号是调用变量的地址,从而达到键盘输入不同的数据【这里的不同数据指的是数据大小不同,而不是数据类型】。%d只能输入整型数据,但可以输入各种大小,比如3,5,7。如果没有取地址符,只是引入了某个数值,达不到键盘任意输入目的。
想必读到这里大家已经对变量有了一定的认识了,恭喜大家又上了一个阶梯!!!
作用域是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段。
C语言中的常量通常有下列几种:
- 字面常量
- const 修饰的常变量
- #define 定义的标识符常量
- 枚举常量
#include
enum Sex
{
MALE,
FEMALE,
SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
//字面常量演示
//3.1415926;//字面常量
//2022;//字面常量
//const 修饰的常变量
const float p = 3.14f; //这里的p是const修饰的常变量
pai = 5.14;//是不能直接修改的!
//#define的标识符常量 演示
#define NUM 100
printf("num = %d\n", NUM);
//枚举常量演示
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
//注:枚举常量的默认是从0开始,依次向下递增1的
//也可赋值依次递增
return 0;
上面例子上的 p 被称为 const 修饰的常变量, const 修饰的常变量在C语言中只是在语法层面限制了变量 p 不能直接被改变,但是 p 本质上还是一个变量的,所以叫常变量。
暂时看不懂枚举常量也没关系,这段代码只是带大家了解接触一下各种常量,后续会详细讲解各个知识点
printf("hello 叶良辰.\n");
这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。
注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。上面字符串的\0省略了,但是在内存中存在【后续了解】
我们要在屏幕上打印一个目录: e:\code\test.c
我们该如何写代码?
#include
int main()
{
printf("e:\code\test.c\n");
return 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 main()
{
printf("%d\n", strlen("abcdef"));
// \62被解析成一个转义字符
printf("%d\n", strlen("c:\test\628\test.c"));
return 0;
}
第7行的\t,\62都被解析成转义字符,大家自行测试一下,感受程序的魅力
- 代码中有不需要的代码可以直接删除,也可以注释掉
- 代码中有些代码比较难懂,可以加一下注释文字
- 注释相当于对代码进行解释,程序不会执行注释的内容
#include
int Add(int x, int y)
{
return x+y;
},
/*C语言风格注释
int Sub(int x, int y)
{
return x-y;
}
*/
int main()
{
//C++注释风格
//int a = 10;
//调用Add函数,完成加法运算
printf("%d\n", Add(1, 2));
return 0;
}
注释有两种风格:
- C语言风格的注释 /xxxxxx/
缺陷:不能嵌套注释- C++风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
如果去了学校,好好学习,就能拿一个好offer,走上人生巅峰。
如果你不好好学习,毕业等于失业,然后只能去工地搬砖了。
这就是选择!
#include
int main()
{
int input = 0;
printf("去了学校好好学习嘛?(选择1/0):");
scanf("%d", &input);
if(input == 1)
{
prinf("好好学习拿到offer\n");
}
else
{
printf("不好好学习去工地搬砖\n");
}
return 0;
}
有些事必须一直做,比如日复一日的学习,没有特殊情况,每天晚上都要休息,这些是生活中的循环。
C语言中如何实现循环呢?
- while语句
- for语句
- do … while语句
//while循环
#include
int main()
{
printf("好好学习\n");
int line = 0;
while(line<=20000)
{
line++;
printf("每天坚持敲代码\n");
}
if(line>20000)
printf("得到好offer\n");
return 0;
}
先简单了解一下循环,后续会详解各种各样的循环
- main函数就是一种函数,程序中不可缺少的函数【程序入口】
- C语言里面的函数和数学中的函数有一定的区别,C语言里面的函数可以没有参数,也可以没有计算的数值,而数学函数需要参数。
- 为什么要使用其它函数呢?
函数便于人们理解和修改程序,不必重新编写多次使用的代码,使用某个功能直接调用相应函数就可以了。【多次使用多次调用】
#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;
}
要存储1-10的数字,怎么存储?
C语言中给了数组的定义:一组相同类型元素的集合
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//定义一个整形数组,最多放10个元素
int arr2[] = {2,3,4,5,6,7,8,9,10,11};
//定义一个整形数组,放10个元素,省略数组个数
格式:
数据类型 变量名[数组个数] = {数据内容};
一维数组的数组个数可以省略
#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]);
}
//当i>=10时数组会越界,程序可能奔溃
printf("\n");
return 0;
}
简单介绍一下各个操作符
+ - * / % 算术操作符
>> << 移位操作符
位操作符 & ^ |
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
-------
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
逻辑操作符
&& 逻辑与
|| 逻辑或
条件操作符
exp1 ? exp2 : exp3
逗号表达式
exp1, exp2, exp3, …expN
下标引用、函数调用和结构成员
[] () . ->
- 除的结果不是1.5嘛,为什么是1呢?
两个整型进行运算,默认的接收他们运算结果的是整型,编译器默认裁剪掉小数点后面的。- 取余想必大家已经看出来了,就是数学中取余数。
剩下的操作符会在后面的文章详解,这篇文章主要带大家了解认识一下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
C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的,关键字有丰富内涵的作用,慢慢了解哦。
注意:关键字,先简单了解,后续详解,一步一个脚印,循序渐进
typedef 顾名思义是类型定义,这里应该理解为类型重命名。
//将unsigned int 重命名为uint, 所以uint也是一个类型名
typedef unsigned int uint;
int main()
{
//观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
uint num2 = 0;
return 0;
}
重命名可以让长的类型转换成短的,降低代码的复杂性,通俗易懂。
//C语言中:
static是用来修饰变量和函数的
1. 修饰局部变量->称为静态局部变量
2. 修饰全局变量->称为静态全局变量
3. 修饰函数->称为静态函数
例1 没有用static修饰的int
例2 使用static修饰的int
一个static让两个代码拥有不同的结果,是不是感受到了代码的神奇性呢?
static让变量的声明周期更长,直至程序结束
没有static的变量出了函数生命周期就结束了
下面几个代码让大家更深刻的了解一下static
//代码1
#include
void print()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
print();
}
return 0;
}
//代码2
#include
void print()
{
//static修饰局部变量
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
print();
}
return 0;
}
对比两块代码更加深刻理解static修饰局部变量的意义。
static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
代码1正常,代码2在编译的时候会出现连接性错误。
一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用
//代码1
//add.c
int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//代码2
//add.c
static int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
代码1正常,代码2在编译的时候会出现连接性错误.
一个函数被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;
}
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的
#include
int main()
{
int num = 0;
// #//取出num的地址
//注:这里num的4个字节,每个字节都有地址,
//取出的是第一个字节的地址(首地址)
printf("%p\n", &num);//打印地址,%p是以地址的形式打印
return 0;
}
地址如何存储呢?需要定义指针变量。
int num = 0;
int *p;//p为一个整形指针变量
p = #
指针的使用:
#include
int main()
{
int num = 10;
int *p = #
*p = 20;
//修改*p就达到了修改num的值
return 0;
}
其它类型也可以使用指针:
#include
int main()
{
char ch = 'Y';
char* pc = &ch;
*pc = 'L';
//通过指针修改数据
printf("%c\n", ch);
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;
}
结论:
指针大小在32位平台是4个字节,64位平台是8个字节
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
描述学生,学生包含: 名字+年龄+性别+学号等信息。
结构体可以把不同类型的数据联系起来
struct Stu
{
char name[15];//名字
int age; //年龄
char sex[5]; //性别
char id[10]; //学号
}s2,s3;
定义结构体的同时可以定义结构体变量
结构体的初始化:
//打印结构体信息
struct Stu s = {"张三", 10, "男", "20091101"};
//.为结构成员访问操作符
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);
- 定义的名字,年龄等信息是结构体成员
- Stu结构体类型名称
- s为结构体变量
本篇文章只是带大家走进C语言,简单了解C语言,很多细节没有详解,在接下来的文章中,我会对C语言的各个模块进行详解。感谢支持,刚开始写博客还有些生疏,多多理解。