C语言学习记录01

目录

1、C语言简介

2、编译问题

3、数据类型

4、如何定义变量

5、内存分配的原则

6、变量赋值、生命周期和作用域

7、全局变量与局部变量

8、变量被定义在内存什么区域


1、C语言简介

1.1、程序的入口:main函数 

main()
{
    /*代码语句*/
}

1.2、程序的返回值:return 值/数据类型;

main()
{
    /*代码语句*/
    return 0;    //0:表示程序正常退出
}

1.3、头文件

1)什么是头文件?

答:头文件是一种包含在源代码文件中的文件,它包含了程序中所需的函数、变量和类型等的声明。

2)有什么作用?

答:为了方便管理和重用代码,它可以被多个源文件共享,从而实现代码的重用和模块化。

3)头文件的种类?

答:头文件可以分为系统头文件和用户头文件两种类型,系统头文件是由编译器提供的,而用户头文件是由程序员自己编写的。

#include <stdio.h>//<>代表引用的头文件是系统头文件,编译器将从系统默认的路径中查找该文件;
#include "123.h"//""代表引用的头文件是用户头文件,编译器将从当前源文件所在目录开始查找该文件。

4)如何引用头文件?

在C/C++中,#include是一个预处理指令,用于将指定的头文件包含在源文件中,以便在程序中使用头文件中定义的函数、变量和类型等。

#include <stdio.h>    //系统提供的头文件
#include "123.h"      //自己准备的头文件

int main(int argc,char* argv[])
{
    printf("Hello,World\n");
    return 0;
}

5)系统头文件里有什么?

函数和变量的声明:头文件通常包含函数和变量的声明,以便在编译时可以让编译器知道它们的存在和类型。这些函数和变量的定义通常在其他源文件中,编译器会将它们与头文件中的声明进行链接。

宏定义:头文件可能包含一些宏定义,这些宏可以用于简化代码,提高代码可读性和可维护性。

数据类型定义:头文件可能包含自定义的数据类型定义,这些类型可以在整个程序中使用。

内联函数定义:头文件可能包含内联函数的定义,这些函数通常在头文件中定义,因为它们需要在编译时进行展开。

模板定义:头文件可能包含模板的定义,这些模板可以用于实现泛型编程。

全局变量声明:头文件可能包含全局变量的声明,以便在其他源文件中使用。

6)系统头文件在哪里?

在 Linux 系统中,头文件通常位于 /usr/include 目录下。

可以使用 find 命令来查找系统中的头文件,例如:

find / -name "*.h"

1.4、命令行传递参数

1)什么是命令行传递参数?

在Ubuntu终端中输入命令执行程序的语句是:./Test0

运行结果:Hello World!

但有的时候也可以是这样:./Test0 aaa bbb

运行结果:Hello World!

2)为什么两种运行结果一样?

答:因为命令行输入的aaa、bbb传递到程序之中,没有对其进行处理。

3)如何在命令行向程序传递参数?

int main()                         //第一种写法
int main(void)                     //第二种写法
int main(int argc,char *argv[])    //第三种写法
/*
 * argc;      argument count:命令行传递的参数的个数
 * argv[];    argument value:用数组记录每一个参数是什么
 */

前两种写法都是代表不接受任何参数,就算是再命令行输入参数,程序也不会接收。

第三种写法就可以实现在命令行输入参数,程序能够接收处理。

#include <stdio.h>

int main(int argc,char* argv[])
{
    printf("argc = %d\n",argc);
    printf("argv[0] = %s\n",argv[0]);
    printf("argv[1] = %s\n",argv[1]);

    return 0;
}

 运行结果:

在ubunt终端上输入:./test01 aaa
运行结果:
argc = 2              //传入参数的个数
argv[0] = ./test01    //第一个参数
argv[1] = aaa         //第二个参数   

1.5、用命令行传递参数的作用?

答:在程序中,对于一些易变的值,用命令行传递参数,可以减少频繁的修改代码,重新编译.........

2、编译问题

2.1、写完代码后,点击编译,编译器在做什么?

答:编译器在检查我们写完的代码在语法上有没有错误。

2.2、点击编译之后会有什么结果?

结果一:编译出错

n error(s),n warning(s)
//代码行出现中文字符  ; 类型赋值不对,数量不匹配等等,不找出问题修改完成,error的个数≠0,
//结果:无法生成可执行的二进制文件

结果二:编译警告

0 error(s),n warning(s)
//例如:使用到printf函数,但是没有包含到stdio.h头文件
//结果:编译不会有报错,但是会报警告,不清零警告也可以生成可执行的二进制文件

结果三:编译通过

0 error(s),0 warning(s)
//没有语法错误,没有缺少内容,
//结果:编译完成之后,直接生成一个可执行的二进制文件

2.3、编译通过:0警告、0报错。那代码就可以实现设计效果?

答:不一定,因为编译通过没有只能说明代码没有语法错误,但在逻辑上是否出错编译器是无法检查出来。

        就像每个字都没写错,但是每个字组合在一起能不能成为一首诗,不一定。

2.4、不同编程语言各自的编译器模式

对于编译器而言,有两种编译模式:

编译模式:C/C++、Go语言... ...下,代码给到编译器中,根据运行平台直接进行编译成可执行的二进制文件。

        优点:性能快,效率高,

        缺点:换一个平台需要重新编译

解析模式:Java、C#、Lua... ...下,代码在给到编译器前需要经过一个解析器,再由编译器进行编译成可执行的二进制文件。

        优点:跨平台,减少编译次数,

        缺点:牺牲性能,效率

3、数据类型

3.1、什么是数据类型?

答:数据类型是描述一个变量在内存中占用了多少个字节的空间。

3.2、数据类型的种类有哪些?

答:一共有两种数据类型:基本数据类型、非基本数据类型。

//基本数据类型:在Linux环境下,系统本来就存在的数据类型,可以直接使用。
char a,short b,int c,long d,float e,double f,bool g;

//非基本数据类型:在Linux环境下,此类数据类型并不存在,在使用之前需对该数据类型进行声明,再使用
char argv[];    //数组
int* p;         //指针
struct T t;     //结构体

3.3、基本数据类型可以存放什么数据?

char a;    //字符型,-2^7~2^7-1
short b;   //短整型,-2^15~2^15-1
int c;     //整型,-2^31~2^31-1
long d;    //长整型,-2^63~2^63-1
float e;   //单精度浮点数,小数点后6位
double f;  //双精度浮点数,小数点后15位

注意:C语言有字符串,但是没有字符串类型

3.4、如何获取数据类型在内存中占用的空间有多少字节数?

答:使用到sizeof();计算数据类型在空间中占用的字节数,返回值是一个长整型数据

#include <stdio.h>

int main(int argc,char* argv[])
{
    printf("%ld\n",sizeof(char));    //1
    printf("%ld\n",sizeof(short));   //2
    printf("%ld\n",sizeof(int));     //4
    printf("%ld\n",sizeof(long));    //8
    printf("%ld\n",sizeof(float));   //4
    printf("%ld\n",sizeof(double));  //8
    return 0;
}

3.5、总结:

1)如果在程序中声明了一个int类型的变量,那么这个变量在内存中就占用了4个字节

2)基本数据类型在内存中占用的空间字节大小还与操作系统有关。

4、如何定义变量

4.1、定义公式?

答:数据类型 变量名;

数据类型:基本数据类型中的任意一个。

变量名:有一套规则。

        ①   由一个或多个字母、数字或下划线组成
        ②   第一个字符必须是字母或下划线
        ③   不能与任何关键字相同

4.2、定义变量的意义

数据类型:决定了这个变量在内存中需要开辟多少字节。

变量名:用一个名称去代表这个变量在内存中所在的地址。

4.3、定义一个整型变量,名称为a

答:int a;

4.4、int a;这句话是什么意思?

答:在内存中连续申请4个字节的空间,然后用变量名a去间接访问这片空间。

5、内存分配的原则

5.1、在创建变量时,内存给变量分配的空间一定是连续的

        例如:给int a;分配了四个字节的空间,在空间中一定是0x0000~0x0003,不会是0x0000~0x0002+0x0004

5.2、内存给变量分配的空间,一定是空闲的,之前的变量已经申请过的空间,就不会被再次申请给新变量。

5.3、内存给变量分配的空间,地址是不确定的。

#include <stdio.h>

int main (int argc,char* argv[])
{
    int a;
    printf("%p",&a);    //%p:输出地址符,&:取地址符
    return 0;
}

5.4、 总结:连续、空闲、不确定

6、变量赋值、生命周期和作用域

6.1、变量的赋值

1)定义一个变量之后,这个变量就可以用来存放数据。那么怎么把想要存储的数据赋值给这个变量?

答:使用变量赋值符" = ",对变量进行赋值,作用就是把等号右边的值赋值给等号左边的变量。

2)变量赋值的方式?

第一种: 定义变量的同时完成变量初始化

int x = 100;    //这个100,就存储在内存中用x代表的空间中
printf("%d",&x);    //结果:100

第二种: 先定义变量,再完成变量初始化

int x ;    //先在内存中开辟一个空间,代号为x,里面存储的数值为随机数
printf("%d",&x);    //结果:随机数
x = 100;   //将100替换掉原本的随机数   
printf("%d",&x);    //结果:100

6.2、变量的生命周期、作用域

1)什么是变量的生命周期?

答:变量从什么时候开始出现在内存空间中,以及什么时候在内存空间中被释放、

2)什么是变量的作用域?

答:这个变量能在程序中起作用的区域。

3)根据作用区域可以将变量分为几种?

答:可分为全局变量、局部变量。

7、全局变量与局部变量

7.1、什么是全局变量与局部变量?

答:程序中不在函数体内部定义的变量就是全局变量,在函数体内部定义的变量就是局部变量。

int x = 100;//全局变量

func()
{   
    int y = 100;//局部变量
    /*代码语句*/
}

7.2、全局变量与局部变量的生命周期有什么区别?

答:区别在于变量什么时候申请内存空间、什么时候释放。

全局变量:在程序开始执行的时候申请内存空间、在程序结束时释放

局部变量:在程序执行至该函数体,在函数体内部申请空间、函数体执行后释放

#include<stdio.h>
    int a = 100;	//全局变量开始申请内存空间
    int b = 200;	//全局变量开始申请内存空间
func()
{
    int c = 300;    //局部变量开始申请内存空间
    int d = 400;
    return 0;       //返回,释放局部变量c、d
}
int main(int argc,char* argv[])
{
    return 0;       //返回,释放全局变量a、b
}

7.3、全局变量与局部变量的作用域有什么区别?

答:区别在于变量在哪些地方可以使用。

全局变量:在程序中任何位置都可以使用。

局部变量:在程序执行至该函数体,在函数体内部使用。

7.4、全局变量和局部变量的初始值有什么区别?

答:区别在于初始值固定与随机。

全局变量:默认都是0。

局部变量:默认都是随机值。

7.5、关于全局变量和局部变量的一些问题?

1)形式参数属于局部变量还是全局变量?

答:局部变量。

2)能不能在不同的函数中定义名字相同的变量?

答:可以。

3)全局变量和局部变量可以同名吗?

答:可以。

8、变量被定义在内存什么区域

8.1、内存区域是怎么分布的?

答:内存区域分为以下几个:栈区.stack、数据段.bss、数据段.data、常量区.rodata

全局变量是在程序执行开始执行时申请内存空间、程序结束时释放空间
#include<stdio.h>
    int a;		    //未初始化的全局变量
    int b = 100;	//已初始化的全局变量
func()
{
    int c;          //未初始化的局部变量
    int c = 100;	//已初始化的局部变量
    return 0;	    
}
int main(int argc,char* argv[])
{
    func();
    return 0;
}

暂时先掌握内存空间分布的4个区域

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值