初步认识C语言

初始C语言

        先简单了解一下计算机语言的发展,计算机语言是从低级语言发展到高级语言,编程的语言一开始是二进制语言(01序列),后面出现助记符(给常用的功能起别名),从而产生汇编语言,汇编语言的使用也不方便,最后诞生了高级语言,而C语言就是一门高级语言。C语言是一门面向过程的代码(关注的是过程,以过程为中心的汇编思想),广泛应用于底层开发(应用软件、操作系统、驱动软件、硬件,C语言就比较擅长中间两个)。

        最开始的时候,每个编译器厂商都对C语言进行改进,厂商之间的C语言并不相同,导致代码不具有跨平台的性质,为了避免C语言语法差异,美国国家标准局出了一套C语言标准,称为ANSI C,使用最广泛的标准是C89和C90。

        编译器:VS2019——集成开发环境(编辑器、编译器、调试器),博客C语言的代码都在VS2019编写。(注:如果使用VS2019编写代码,scanf可能会出错,就在CSDN搜索 VS2019scanf 解决。)

C语言程序

        第一个程序

#include <stdio.h>

int main()
{

	printf("Hello World!\n");

	return 0;
}

        C语言程序中,先写主函数(main函数),操作系统会通过调用主函数来运行程序,主函数的返回类型是int类型(整型),最后需要用return返回一个整数,这里返回0就好,它结束了函数的执行。主函数是程序的入口(一个工程中,主函数有且仅有一个),运行程序会先来到主函数的第一行,如果程序没有主函数,无法运行。(注:代码用的符号都是英语符号,要将输入法改为输入英语的)

        printf是C语言的库函数,功能是按照某种指定格式在屏幕上打印数据(可以搜索 printf格式化输出 阅读一下),库函数的使用,需要使用#include< >包含对应的头文件,printf的头文件(后缀是.h的文件)是stdio.h。

        \n是转义字符,\后面的字符失去了它原本的意思,转变成特殊的含义。\n的意思是:回车换行,将当前位置移到下一行的开头。

数据类型

        计算机语言是人和计算机交流的语言,为了解决人们生活中出现问题,那么就必须描述清楚数据的类型。

       C语言中提供的数据类型——内置类型:char(字符数据类型)、short(短整型)、int(整型)、long(长整型)、long long(更长整型)、float(单精度浮点数)、double(双精度浮点数)、布尔类型...。

        计算机中的单位:1 GB = 1024 MB = 1024*1024 KB =   1024*1024*1024 byte(字节) = 1024*1024*1024*8 bit(比特,一个bit存放一个0或者一个1)

        sizeof用来计算数据大小,单位是byte。

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

        布尔类型只有两个值:true和false,对应的是真和假,通常用来作为判断条件,需要包含头文件 stdbool.h 才能使用。

bool flag1 = true;
bool flag2 = false;

        自己创造的类型——自定义类型。

变量

        定义变量要选择合适的数据类型,变量的数据类型直接决定了它所占内存空间的大小和布局方式,该空间存储值的大小,以及能使用的运算法。

定义变量

类型 变量名

        定义变量的同时,进行赋值叫做初始化,对已经存在的值进行赋值才叫赋值。

	// 字符类型,字符需要加上''
    char ch = 'a';
	int a = 10;
    // float数据后面要加上f
	float f = 1.1f;
	double d = 2.2;

    // 同时定义多个变量
    int b = 0, c;
    // 赋值
    b = a;

        定义变量不能连续赋值

int a = b = c = 1;

全局变量、局部变量

         {}外面的变量是全局变量,{}里面的是局部变量。

#include <stdio.h>
int a = 20;

int main()
{
	int b = 10;
	return 0; 
}

       a是全局变量,b是局部变量。

        全局变量和局部变量同名时,局部变量优先使用(同名并不是同一个变量,而是不同变量!)。定义全局变量不初始化,它的值默认是0;定义局部变量不初始化,它的值默认是随机值。(因为编译器的原因,变量不能未初始化或者赋值就使用,用一个数组查看一下局部变量不初始化是随机值)

使用变量

	// 定义变量
    int a = 0;
	float f;
    // 输入值
	scanf("%d %f", &a, &f);
    // 打印值
	printf("%d %f\n", a, f);

         使用scanf进行格式化输入,对变量需要使用&这个符号,是取地址的意思,找到变量所在的空间,将输入的值存储在这个空间。scanf也是库函数,头文件是stdio.h。自行  学习一下格式化输入。

变量的作用域和生命周期

        作用域:能够直接使用变量名的地方就是该变量的作用域。

        全局变量的作用域:整个程序。

        局部变量的作用域:变量所在的局部范围

        可以跨源文件(后缀为.c的文件),但是需要使用 extern 类型 变量名 来声明变量!(不要初始化,如果初始化相当于是定义。 )

        局部变量的作用域是所在的{}里面。

	{
		int a = 10;
		printf("%d", a);
	}
	printf("%d", a);

        这里第二个printf就不认识变量a了,因为变量a出了{}之后就销毁了,程序编译错误。

        全局变量的生命周期:整个程序。

        局部变量的生命周期:变量创建到出作用域的范围,出了作用域,变量销毁。

常量

        具有常属性,不能修改的值。

字面常量

        直接写出来的值。

        字符常量、字符串常量、整型常量、浮点数常量

'a'
"abc"
1
1.1

const修饰的常变量

        具有常属性,不能修改变量的值。

        本质上还是变量,定义数组的大小要使用常量(注:c99标准引入变长数组,能够使用变量定义数组大小,变长数组不能初始化!)

#define 定义的标识符常量

        就是一个常量,可以用来定义数组大小。

#define N 5
int main()
{
	int arr1[5];
	int arr2[N];
	return 0; 
}

枚举常量

        使用关键字enum,在定义中列举出所有可能的取值,使用在能够一一列举的情况,例如工作日和休息日。可以定义数组大小。枚举类型中的枚举元素是默认从0开始的,每往下一个元素递增1。

enum day
{
	weekday,
	restday
};
int main()
{
	enum day day1 = weekday;
    int arr[restday];
	return 0; 
}

        可以在定义枚举类型的元素后面给值,改变枚举元素的值。

数组

        一组相同元素的合集。

定义数组

类型 数组名[常量]

char arr[5];//定义数组
char arr1[] = "ab";//数组元素个数为初始化内容大小,大小为3
char arr2[5] = "qw";//不完全初始化,剩下的默认为0
int arr3[5] = { 1,2,3,4,5 };//完全初始化;

数组下标

        数组下标是从0开始的,可以通过 数组名[下标] 访问数组元素。

字符串

        放在 "" 双引号里面的一串字符称为字符串。字符串的结尾隐藏了一个字符 '\0' ,也算作字符串的内容,字符串以 '\0' 作为结束标志。

char arr[] = "abcd"

字符初始数组与字符串初始化数组

char arr1[] = { 'a', 'b', 'c', 'd' };
char arr2[] = "abcd";

        arr1数组开辟了4个字节的空间存储数据;arr2开辟了5个字节的空间存储数据,第5个字节存储 '\0' 。

        内存是一块连续的空间,计算字符串长度、打印字符串都会找到 '\0' 才结束。计算字符串长度的时候,'\0' 不算入字符串长度中。

        strlen是库函数,用来计算字符串长度,字符 '\0'不算进字符串长度中,头文件是string.h

        arr1数组在内存中存储了abcd,后面存储的不知道是什么,但是会找到 '\0' 才结束,所以计算的字符串长度是随机值,后面打印的也是随机值(并不是每次都一样)!

        arr2数组在内存中存储了abcd\0,计算字符串长度、打印字符串遇到自身存储的 '\0' 就结束了。

转义字符

        在字符前面加 \ 转变它原来的意思。

百度百科的图

        可以自己测试一下转义字符。每一个字符都有自己ASCII码值,一共128个字符,ASCII码值从0到127。最后两个转义字符一定要理解。

        \八进制的范围是 0 ~ 177。 \x十六进制的范围是 0 ~ 7f。(学习一下进制转换)

选择语句

if

        通过判断条件是否符合来执行语句。(条件成立为1,条件不成立为0,非0为真)

if (条件判断) {执行语句;}

if (条件判断) {执行语句1;} else {执行语句2;}

if (条件判断) {执行语句1;} else if (条件判断) {执行语句2;} else {执行语句3;}

int n = 11;
if (n % 2 == 1)
{
    printf("%d是奇数", n);
}
else
{
    printf("%d是偶数", n);
}

switch

        通过表达式进入对应的case执行语句。

switch (表达式)

{
        case 常量表达式:  执行语句;  break;
        case 常量表达式:  执行语句;  break;
        ...
        default:  执行语句;  break; //没有对应的case到default执行语句。

}

循环语句

        通过循环语句反复执行语句。

while (条件判断) {循环语句;}

do {循环语句;} while (条件判断);

for(单次表达式; 条件判断; 末尾循环体) {循环语句;}

函数

        函数分为库函数和自定义函数,函数能够让代码只保留一份,调用函数会跳转到函数所在的位置,如果没有函数,实现相同的功能就要重复书写相同的代码,代码重复,非常的冗余,开发效率低。函数就是一个手机加工厂,把原材料提供给工厂,工厂对原材料进行加工,最后返回产品,我们只需要学会需要提供什么参数,如何使用函数,并不需要了解加工的方式,得到最后的返回结果就行,就像printf库函数。

返回类型 函数名(参数)

函数调用

函数名(参数) 

学习库函数

        可以考虑在电脑上下载一个MSDN学习库函数的使用。

        中文网址:http://zh.cppreference.com

        英文网址:www.cplusplus.com

        如果你知道库函数的名字可以直接搜索,如果想学习头文件里的库函数,可以点击左边的Reference,再点Clibrary就可以看到头文件了,点击对应的头文件,就能看到该头文件下的库函数。学习编程,能看懂英文文献是程序员的基本素养(最好尝试去看英文的)。

操作符

运算操作符

+        -        *        /        %

        /:两边都是整数的时候,进行整数除法,不保留后面小数;一边有浮点数才进行浮点数除法

位操作符

&        |        ^        ~

        对整型补码的二进制位操作,操作数必须是整数。

        &(按位与):两个二进制位都为1的时候为1,只要有0就为0。

        |(按位或):两个二进制位只要有1的时候为1,都为0才为0。

        ^(按位异或):两个二进制位相同的时候为0,不同的时候为1。

移位操作符

>>        <<

        对一个整型补码的二进制位进行移动,操作数必须是整数。

赋值操作符

=        +=        -=        *=        /=        &=         ^ =        |=        >>=        <<=

        +=:例如 a += 2; a先+2再将得到的值赋值给a。

单目操作符

!        -        +        &         sizeof          --        ++         *         ( 类型 )

        !:条件取反。真变假,假变真。 

        &:取地址操作符。

        sizeof:计算数据大小,单位是byte(字节),返回类型是size_t的无符号整数。

        --:让变量减1,分为前置--和后置--。

int a = 5;
int b = a--;    // 先将a的值(5)值赋值给b,a再减1,a变为4
int c = --a;    // a先减1,a变为3,再将a的值(3)赋值给c

        ++:让变量加1,也分为前置++和后置++。

        (类型):强制类型转换。

关系操作符

>         >=        <         <=        !=        ==

        不能像数学一样连续判断,这种是错误的

if (10 <= 20 <= 30)

        需要使用逻辑操作符

if (10 <= 20 && 20 <= 30)

逻辑操作符

&&       ||

        &&:多个条件判断,全部条件都为真,整个判断条件就为真,有一个条件为假就为假。(依次判断,遇到假,后面不再判断)

        ||:多个条件判断,只要有条件为真,整个判断条件就为真,全部条件为假就为假。(依次判断,遇到真,后面不再判断)

条件操作符

判断条件  ? 执行语句1  : 执行语句2
int a = 5 > 3 ? 5+3 : 5-3;

        条件成立执行前面的,条件不成立执行后面的。

逗号表达式

表达式1 , 表达式2 , ..., 表达式N

        从左往右依次执行,有()的情况下,()里面的所有表达式是一个逗号表达式,整个表达式的结果为()内最后的一个表达式的值。

int a = 3;
int b = 0;
b = (a + 2, a--, a + 5);

         a+2,不改变a的值;a--,a变为2;最后把a+5的值(7)赋值给a。

        从左往右依次执行,没有()的情况,所有表达式是一个逗号表达式。

int a = 3;
int b = 0;
b = a + 2, a--, a + 5;

        从左往右依次执行,b=a+2是第一个表达式,将a+2的值(5)赋值给b;a--,a变为2,a+5,不改变a的值。

数组下标、函数调用、结构体成员访问操作符

[]        ()        .         ->

        []:访问数组元素。 

        ():函数调用,函数名和()要连在一起,中间不能有空格。

        .:结构体变量访问成员操作符

        ->:结构体指针变量访问成员操作符。

关键字

        关键字是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

        先简单认识几个,有一些后面会重点讲。

        auto:局部变量前面可以加auto,现在省略了。

        extern:声明外部符号(变量、自定义类型等等)。

        typedef:对类型重命名。一般对复杂类型名重命名。例如结构体。

typedef unsigned int uint;

         register:寄存器关键字,寄存器的运算速度非常快,建议将变量的值放进寄存器中,能够更快的运行,取决于编译器。

register int a = 1;

         寄存器是集成在CPU上的,寄存器的速度非常快。存储体系结构:寄存器、高级缓存(三级缓存)、内存、硬盘、网盘。从左往右速度越来越慢,价格越来越便宜。早期的时候,CPU和内存的速度都差不多,CPU的数据的从内存中获取,随着技术的发展,CPU的处理速度越来越快,内存速度跟不上,然后产生了高级缓存和寄存器,先将内存的数据放进高级缓存,高级缓存的数据放到寄存器,整体的速度就上升了。

static

        static用来修饰变量和函数。

        局部变量

        变量a每次进入{}的时候创建,出{}的时候销毁,重复十次,每次进入{}都是重新创建,所以打印十次1。

        static修饰局部变量

        static修饰局部变量之后,作用域还是跟局部变量一样,但是生命周期变为整个程序,出了作用域不销毁,是因为a存储在静态区。注意:并没有从存储在栈变为静态区的过程,而是就存储在静态区。

        全局变量跨源文件

        全局变量具有外部链接属性,能够跨源文件使用。

        static修饰全局变量跨源文件

        程序链接错误。static修饰跨源文件的全局变量,该全局变量具有的是内部链接属性,只能在自己的源文件使用,不能跨源文件使用。该全局变量的生命周期不变,作用域变小了。

        函数和static修饰的函数跟全局变量和static修饰的全局变量一样。

#define定义的常量和宏

        #define定义的常量和宏一般全大写。

        程序是通过预处理、编译、汇编、链接,最后才成为可执行程序.exe。

#include <stdio.h>
#define N 10//常量
#define ADD(x,y) ((x)+(y))//宏
int main()
{
	int arr[N];
	int a = 4;
	int b = 5;
	int c = ADD(a, b);
	printf("%d", c);//9
	return 0; 
}

         #define定义的标识符和宏、包含头文件在预处理阶段完成替换。

//.....stdio.h头文件展开
int main()
{
	int arr[10];
	int a = 4;
	int b = 5;
	int c = ((a)+(b));
	printf("%d", c);//9
	return 0; 
}

        宏的功能和函数非常像,宏名、函数名,都可以传参,但是宏的参数没有类型,宏业没有返回值,宏不能像函数一样实现递归(自己调用自己)。

内存

        内存是计算机的重要存储器,计算机的程序都是在内存中运行的,内存只能暂时性的存储数据,断电就会丢失数据。内存是一块很大的空间,将内存划分为一个个内存单元,内存单元的大小是一个字节,给每个内存单元都编号,编号就是内存单元的地址,可以通过地址访问内存单元的数据。内存就像生活中的城市,内存单元就像城市里的房子,内存单元的地址就像房子的地址,有了房子的地址,就能找到房子,访问房子里面的人。32位平台下,内存编号是32根地址线或者32根数据线通电后,通过高电平或者低电平的电信号转换成数字信号1或0,有2的三十二次方个编号,从0x00000000到0xFFFFFFFF,内存大小为4GB。 

         数据的地址是 存储数据最小的那一个地址,访问数据的时候往地址后面找。

指针

        指针就是内存地址,指针变量是用来存储内存地址的变量。指针变量的类型要对应存储变量的类型再加一个*,口头上的指针一般都是指针变量。

char ch = 'a';
char* pch = &ch;
*pch = 'b';

        char*的*是指明pch是指针变量,*前面的char表示存储地址的对象是char类型的。

        *pch是通过地址找到数据,再把数据ch改为 'b' 。(*是解引用操作符)

指针大小

        指针大小跟存储的数据类型没有关系,因为存储的是地址,地址多大是跟多少位平台有关。

        32位平台的情况下,指针大小是4个字节。地址都是32个0 1序列,需要4个字节。

        64位平台的情况下,指针大小是8个字节。地址都是64个0 1序列,需要8个字节。

结构体

        一个描述复杂数据的数据类型。人的属性就有很多,例如身高、体重、年龄、名字等等。用struct关键字定义结构体。

struct people
{
    double high;
    double weight;
    int age;
    char name[10];
};

定义结构体变量

struct people p = {170.5, 111.5, 20, "zhangsan"};

结构体成员访问操作符

struct people p = { 170.5, 111.5, 20, "zhangsan" };
struct people* pp = &p;

//结构体变量访问成员
printf("%lf %lf %d %s\n", p.high, p.weight, p.age, p.name);

//结构体指针变量访问成员
printf("%lf %lf %d %s\n", pp->high, pp->weight, pp->age, pp->name);

注释

        一些复杂的程序代码可以加上文字注释,注释帮助读者理解代码(文字注释很重要)。不需要的代码可以删掉或者注释掉。编译器会忽略注释,因此注释对程序的性能并不会有影响。

C语言的注释风格:/*aaaaa*/        不能嵌套注释,/*会遇到第一个*/结束

C++的注释风格://aaaaa        可以一行注释也可以多行注释       

        C语言也可以使用C++的注释风格。

        错误的注释比完全没有注释更加糟糕,会误导读者,修改代码的时候记得同步更新注释。

良好代码风格

        一句一行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值