C/C++系列之变量声明与使用——新手必须掌握的基础技能二
变量声明与使用
- 一、C/C++中的基本数据类型
- 二、C/C++ 中的保留关键字
- 三、变量声明与使用
- 1、变量的声明方式
- 1.1、变量声明而未初始化下的垃圾数据
- 1.2、变量声明与初始化
- 2、变量的使用
- 2.1、全局变量与局部变量
- 3、常量
- 4、静态变量
- 四、数组变量的声明与使用
- 1、数组分类
- 2、数组声明方式与初始化
- 2.1、一维数组的声明
- 2.2、一维数组的初始化
- 2.3、一维数组的取值与修改
- 3、二维数组
- 4、高维数组
- 五、自定义数据类型
- 1、结构体
- 1.1、结构体声明方式
- 1.2、结构体示例
- 1.3、结构体变量声明与简单使用
- 2、类体
- 2.1、类声明方式
- 2.2、类的简单使用
- 在上一期中,已经对 C/C++ 中的输入与输出进行了较为系统的学习,接下来将又是一个新手基础阶段的又一个重头戏:
变量的声明与使用
。 - 在开始正文之前,请在上一期的工程项目的头文件文件夹中新建一个头文件:
AboutVariable.h
,接下来的所有与变量相关的代码都会在这个头文件中编辑。市面上很多C/C++编程基础学习的书籍,都有一个通病,那就是每个简单的基础示例都要新建一个工程项目,简直就是大材小用、浪费磁盘空间。你跟着我学习,我将带领你体验把整个编程基础阶段的代码组织在同一个工程项目的经验,这对你以后复习也是相当用帮助的。 - 另外,可以的话,去GitHub申请一个账号,然后把自己的项目以公开形式托管到GitHub上面。
- 本篇博文将包括以下内容:
1)C/C++ 中的基本数据类型
2)C/C++ 中的保留关键字
3)基本变量的声明方式
4)基本变量的简单使用
5)变量的有效范围
6)数组变量的声明与使用
7)结构体与类体的引入及其简单使用
8)自定义数据类型及其声明与使用
一、C/C++中的基本数据类型
- 所谓 C/C++ 的基本数据类型是指
由 C/C++ 官方提供的,即只要装了运行环境就可以使用的数据类型
。 - 根据数据内容可以划分为
数字型数据类型和字符型数据类型,以及一个特殊的无类型(void)
,前者又可以进一步地根据数据的组织形式划分为:无符号整型(unsigned)、整型(短整形short、整型int和长整型long)、单精度浮点数(float)、双精度浮点数(double)和布尔型(bool)
;而字符型的细分便比较少,只分为普通字符型(char)和宽字符型(wchar_t)。 - 在数字数据类型中
unsigned、short、long
可以作为修饰符进行组合放在 int 前面,例如:short int、long int 、unsigned short、unsigned long int 等,都是合法的(指符合C/C++语法,而非现实中的法律法规
);long 可以修饰 double。 - 各种数据类型的具体介绍如下表:
二、C/C++ 中的保留关键字
- 之所以在介绍了 C/C++ 基本数据类型后,紧接着在这里进行保留关键字的介绍,是为了避免初学者在后面学习声明变量时,将变量名命名为保留关键字导致编译不通过。
- C/C++ 中的保留关键字并不是很多,所有保留关键字都如下表:
- 这个表格中的单词或字符序列,不得用于变量名,非得用的话,至少开头大写或全部大写。
三、变量声明与使用
1、变量的声明方式
1.1、变量声明而未初始化下的垃圾数据
- C/C++ 遵循严格的语法规范,要使用一个东西去存储数据,就必须声明相应数据类型的变量(
操作系统内部,会根据变量声明语句给程序分配寄存器或内存单元
),并且变量声明之后,在使用之前必须进行一次初始化。这是为什么呢? - 这是因为声明一个变量就像当于程序向操作系统申请一个寄存器或内存单元,而这个寄存器或内存单元里面不是没有东西的,因为这些寄存器或内存单元一直处在系统地分配与回收操作中,并且系统回收寄存器或内存单元时,并不负责进行对立面的东西进行清空;而这些由上一次使用寄存器或内存单元的程序留下来的东西,对于本次使用寄存器或内存单元的程序来说,是完全没有用处的,只会造成程序的错误,因此这些遗留的东西被称之为
垃圾数据
,你可以像我下面要做的一样,在 Visual Studio 跑一跑下面的代码,看看控制台会输出什么内容?void testRubbishDatum(void) {int a;cout << "未初始化的变量a的内容:" << a << endl; }
- 编译器直接不给编译通过,并弹出错误窗口。
1.2、变量声明与初始化
- 因此,在进行变量声明后,使用之前必须进行初始化,而根据初始化的时间的不同,变量声明方式和初始化方式分为下面两种:
Type variable; // 单独声明变量不进行初始化 variable = Initial_data;// 单独进行初始化 Type variable = initial_data; // 声明的同时进行初始化
- 接下来,对上面的基本数据类型进行逐一尝试,并复习上一期的格式化输入与输出,我给出一个模板示例,剩下的靠自己动手。想要正在掌握技能,必须自己多主动动手、独立思考。
- 模板例子如下:
void templateOfUsingDataType(void) {int a;cin >> a;int b = 1456;printf("a=%d\n", a);cout.width(6);cout.fill('#');cout << setiosflags(ios::right);cout << b << endl; }
2、变量的使用
- 变量在经过声明和初始化之后,便可以开始使用了,但为了能够正确使用变量,你有必要理解变量的作用范围,即有效域。为了方便新手理解,我打个比方:变量声明就是相当于报考某个大学,变量声明成功就好比成功考上了这个大学,接着变量初始化就好比去学校报道、注册和领取校园卡什么的,而这个校园卡在这个大学范围内就是有用的,可以用来刷门禁、饭堂吃饭什么的,一旦离开这个学校,到了其他学校,那么校园卡就是一张普通的硬卡片而已,一点用都没有。
2.1、全局变量与局部变量
- 根据变量作用域的大小可以划分为
全局变量和局部变量
,记住这个全局
不是一个静态的,是一个动态的范围,例如,一个头文件没有被工程项目里的其他头文件或源文件引用的情况下,那么此时的“全局”仅限于当前头文件,而一旦被某个头文件或源文件引用了,那么此时的“全局”由当前头文件和引用该头文件的文件两个文件范围构成。 - 全局变量,
指在任何函数体外、直接在文件中声明的变量
,相反的,在某个函数体内声明的变量就是局部变量
。因此,我们此前使用的变量都是局部变量。全局变量在声明全局内,无论哪个函数都可以使用,而局部变量则只能在所声明的函数体内使用;因此,我们通常将全局变量作为公有变量,而局部变量则作为私有变量或临时变量。// 假设这个代码块就是一个头文件 int a; // 这是一个全局整形变量void afun(void) {int b; // 这是一个整型局部变量 } void anotherfun(void) {a=10; // 因为 a 是全局变量,因此 a 在这里有效b=1; // 错误,因为 b 只是 afun 中的局部变量 } void alsoanotherfun(void) {afun();b=1; // 错误,函数体的范围不能通过引用进行扩展,头文件才可以 }
- 新手的你,看到上面这个例子,就一定要记牢了,
只有头文件可以通过被引用来扩展有效范围,函数不能通过被引用来扩展有效范围
。为了避免因变量范围问题造成程序错误,就一定要注意好变量的范围。一个函数想要使用其他函数体内的局部变量,唯有通过传参
,这个不是当前的学习重点,传参会放在后面的函数的详细讲解中。
3、常量
- 变量,之所以叫变量,是因为它的数值可以在声明后进行修改;与此相反的,一种一旦声明那么它的值就固定下来不能改变就是常量。
- 常量的声明方式有
宏定义法和const修饰法
。宏定义,一般在文件头部,用define
关键字进行声明,其格式:#define varname data
;而 const 修饰法就是在普通变量的声明方式的基础上加用 const 修饰,例如:const int a = 5;
。这两种方式在实际使用时,有如下区别,宏定义法通常用于声明全局常量,而 const 修饰法大多用于声明局部常量。看下面的一个例子:
- 不用编译,编辑器已经提示错误“表达式必须是可修改的左值”。
4、静态变量
- 这是一种特殊的变量,既不像常量那样不允许修改,又不像普通变量那样每次调用会恢复初始值。静态变量,“静”在程序运行时一经使用就不会恢复初始值。也就是说,如果声明赋值为 12,那么第一次调用时值为 12 并修改为 15,下一次重新使用时就不在是 12 而是 15 了。
- 静态变量的声明也是通过在声明普通变量的基础上加上
static
关键字,例如 :static int a = 10;
。进行修饰的。静态变量也分为全局静态和局部静态。下面我给出一个例子,带领大家体验静态变量的特点。void fun(int &num1, int &num2) {static int a=12;int b = 10;b=b+1;a=a+12;num1=b;num2=a; } int main(int argc, char** argv) {int x1=0,y1=0,x2=0,y2=0;fun(x1,y1);std::cout<<"x1="<<x1<<",y1="<<y1<<std::endl;fun(x2,y2);std::cout<<"x2="<<x2<<",y2="<<y2<<std::endl;return 0;}
x1=11,y1=24 x2=11,y2=36
- 我在 main 函数里面调用了两次 fun 函数,对于变量 b, 你会发现两次调用的结果是一样的,而变量 a 却是在累加。这就是静态变量的特点。
四、数组变量的声明与使用
- 如果把变量声明的行为,比做租房子,那么非数组变量的声明就是一次租一间房子,而数组变量的声明就是一次租好几间房子,租的房子可以在同一层楼也可以不同层,可以紧邻也可以不相邻,可以同一栋也可以不同栋。
- 如上图,每一个小方格就称为数组的一个元素。
1、数组分类
- 根据数组元素的数据类型,可以分为数字类型数组和字符数组(就是字符串,所以记住:
字符串不是基本数据类型
)。 - 根据数组所在的空间可以分为
静态数组和动态数组(指针数组)
。静态数组是在程序栈上申请分配空间,而动态数组则是在堆上申请分配空间。注意,这里的栈堆是一种数据结构、系统提供的数据结构,不是这里的学习重点,因此你只要记住:静态数组和动态数组申请分配的空间是不一样的
。 - 根据数组的维度(参照坐标系进行理解)分为一维数组、二维数组及高维数值。
2、数组声明方式与初始化
2.1、一维数组的声明
- 数组如何声明呢?数组的具体声明,根据要声明的数组是否动态有下面两种:
type var_name[length]; // 静态数组声明 // 例如声明一个长度为 10 的整形数组: int a[10]; type* var_name = new type[length]; // 动态数组声明,示例如下: int* a = new int[10]; int length=10; int *b = new int[length];
- 声明静态数组是,指定数组长度的必须用整形常量,而动态数组既可以用整形常量也可以用整形变量指定数组长度。同变量一样,数组声明之后要进行使用必须进行初始化。
2.2、一维数组的初始化
- 同变量一样,对于静态数组的初始化可以同声明一起,也可以单独进行,值得强调的是,若要单独初始化数组则必须要用到循环体(程序结构的一种)。示例如下:
int a[5] = {12, 5, 47, 9, 6]; char s[6] = "abcde\0"; // 这是第一种数组初始化方式,字符数组的声明长度要比实际长度多一个单位,因为字符串必须有结束符 int a[] = {12, 5, 47, 9, 6]; char s[] = "abcde\0"; // 第二种方式,与第一种的区别就是没有显式指定数组长度 // 这两种方式都是将目的数据直接赋给数组, //下面的就是不赋值目标数据,而是先用一个初始数据,此时就必须显式指定数组长度 int a[5] = {0]; char s[6] = ""; // 单独初始化的方式 // 数字数组和字符数组稍微有点不同 int a[5]; for(int i=0;i<5;i++)cin>>a[i]; char s[5]; cin>>s; // 注意只能最多输入5个字符
- 对于动态数组,只能单独初始化,如果是数字数组就只能通过循环赋值,字符串到可以直接输入连续的字符。
2.3、一维数组的取值与修改
- 一维数组的取值方式如下:
// 数组名[下标值] 下标从0开始,因此长度为 10 的数组,其有效下标范围是0~9(length-1) int a[5] = {12, 5, 47, 9, 6]; char s[6] = "abcde\0"; a[2]; s[1];
- 当下标取值>=length 时,系统会抛出越界异常,导致程序运行中断、结束。
- 单独修改某个数组元素的时候,可以用
数组名[下标]=新值
的方式进行。
3、二维数组
二维数组声明方式如下:
int a[3][3] = {{1,2,3},{1,2,3},{1,2,3}} // 可以简单理解为二维数组的元素是一个一维数组char s[2][3] = {"12\0","12\0"}; // 二位字符数组以字符串为元素// 二维静态数组单独初始化int b[5][6]for(int i<5;i++)for(int j=0;j<6;j++)b[i][j]=data; // cin>>b[i][j];// 二位动态数组声明,要记牢int **a = new int*[5];for(int i=0;i<5;i++)a[i] = new int[5]);// 二维动态数组初始化,和静态二维数组单独初始化的方式一样
二维数组取值,通过两个下标确定,就如上进行初始化赋值时的代码。
4、高维数组
- 普通变量可以特殊化为只有一个元素的一维数组,一维数组就相当于只有一个元素的二维数组,那么二维数组是否可以理解为只有一个元素的三位数组呢?可以这么理解。那么可不可以在二维数组的声明格式上进一步推广,推广出三位数组的声明格式是:“int a[2][2][2]”,遗憾地告诉你,
不可以!
。静态数组,就我所知的编译器中,还不支持通过三个中括号连用的形式来声明三位数组;动态数组却可以通过连用三个*
来声明三位数组:int ***p; // 这就是一个三位数组p = new int**[length];for(int i=0;i<length;i++)p[i] = new int*[length];for(int i=0;i<length;i++)for(int j=0;j<length;j++)p[i][j] = new int[length];
- 给个三位数组示例:
int ***p; // 这就是一个三位数组int length = 5;p = new int**[length];for(int i=0;i<length;i++)p[i] = new int*[length];for(int i=0;i<length;i++)for(int j=0;j<length;j++)p[i][j] = new int[length]; for(int i=0;i<length;i++)for(int j=0;j<length;j++)for(int k=0;k<length;k++){*(p[i][j]+k)=1;} for(int i=0;i<length;i++){for(int j=0;j<length;j++){for(int k=0;k<length;k++){std::cout<<*(p[i][j]+k)<<" ";}std::cout<<std::endl;}std::cout<<"++++++++++++++++++++++++++"<<std::endl;}
- 三维以上的高维数组,只能通过动态数组即指针数组来实现。
五、自定义数据类型
- 以上,就是由 C/C++ 官方提供的基本数据类型及其对应的数组的相关内容。
- 在实际生产过程中,光靠这些基本数据类型和数组还不够,例如学生信息这样的复合数据类型,便不能由基本数据类型来表示了,因为一条学生信息包括学生名字、学生年龄、班级等等,包含至少两种以上基本数据类型。
- 为了能够在程序中表示这些复合数据类型,C/C++ 提供了一套机制,允许我们去自定义数据类型,这套机制在 C 语言中称之为
结构体
,而在C++ 中则称类体
。
1、结构体
- 在 C 语言中,通过使用结构体来进行自定义数据类型,结构体的关键字为:
struct
。
1.1、结构体声明方式
- 结构体声明方式如下:
// 说明以下,typedef 并不是声明结构体的必要,可以加或不加,加的话是为了能够给结构体另取名字 struct [struct_name] {type1 member1; //成员变量1type2 member2; // 成员变量2…… }; typedef struct [struct_name] {type1 member1;type2 member2;…… }[another_struct_name];
- 结构体中的变量称之为
成员变量
。
1.2、结构体示例
- 以学生信息为例创建一个结构体,如下:
struct MyStudent {char name[12]; //学生姓名int age; // 学生年龄bool sex; // 1-boy,0-girl };
1.3、结构体变量声明与简单使用
- 结构体变量声明方式有两种,一种是静态声明,另一种是动态声明:
StructNmae varName;StructName* varName = new StructName;
- 我们以上面的学生信息结构体进行声明尝试,为了能够输出内容,先对结构体进行修改,将成员变量公有化。
struct MyStudent {public:char name[12] = "Tom"; //学生姓名int age = 24; // 学生年龄bool sex = 1; // 1-boy,0-girl }; void testMyStudent(void) {MyStudent stu01;MyStudent* stu02 = new MyStudent;cout << "name=" << stu01.name << ",age=" << stu01.age << ",sex=" << stu01.sex << endl;cout << "name=" << stu02->name << ",age=" << stu02->age << ",sex=" << stu02->sex << endl; }
- 在 main 函数里调用,输出内容如下:
- 同样的,结构体变量也是可以声明数组的,这里先不展示,等到后面详细讲解类与结构体时,再展开来;现在你先学习这些。
2、类体
- 在 C++ 中,虽然也可以用结构体进行自定义数据类型,但这不符合标准 C++ 的风格,
标准 C++ 就是一切都要以 C++ 的语法进行
,在标准 C++ 中,声明自定义类型,通过类来进行。 - 类用关键字
class
进行声明
2.1、类声明方式
- 其实,类的声明与结构体声明很类似,只不过将声明关键字改了:
class class_name {public:type01 member01; // 成员1type02 member02; // 成员2…… };
- 类与结构体不同的地方在于,
不允许成员变量声明的同时进行初始化
。
2.2、类的简单使用
- 类的使用称之为
实例化
,同样的以学生信息进行类声明与简单实例化:
class Student
{public:char name[12] = "Tom"; //学生姓名int age = 24; // 学生年龄bool sex = 1; // 1-boy,0-girl
};
void testStudent(void)
{Student stu;cout << "name=" << stu.name << ",age=" << stu.age << ",sex=" << stu.sex << endl;Student* stu02 = new Student;cout << "name=" << stu02->name << ",age=" << stu02->age << ",sex=" << stu02->sex << endl;
}
- 输出和刚刚的一样。
- 以上内容就是对结构体和类体的简单初步认识和简单实用,更多内容在后面会剖析。
- 以上,就是关于 C/C++ 变量的内容,当然我这只是一个提纲挈领的作用,更多还是要靠你自己多进行变量声明使用的代码编写与运行,正所谓师傅领进门,修行看个人,加油!
C/C++系列之变量声明与使用——新手必须掌握的基础技能二相关推荐
- python定义字符串变量有两种常用方式_Python 1基础语法二(标识符、关键字、变量和字符串)...
一.标识符 标识符就是程序员自己命名的变量名.名字需要有见名知义的效果,不要随意起名 :比如 a=1 a是个变量,a这个变量名属于标识符 1 company = '小米 2 employeeNum = ...
- 【TypeScript系列教程07】变量声明
目录 TypeScript 变量声明 实例 类型断言(Type Assertion) TypeScript 是怎么确定单个断言是否足够 类型推断 变量作用域 TypeScript 变量声明
- 必须声明标量变量 @sum_level。_ES6系列—新的变量声明方式
在ES5中,变量声明只有var和function以及隐式声明三种,在ES6中则增加了let.const.import和class四种. 1. let 1.1 块级作用域 let声明的变量的作用域是块级 ...
- 可以声明一个抽象类类型变量_TypeScript系列(二)变量声明和数据类型
一,变量声明 TypeScript是JavaScript的超集,在变量声明方式方面,关键字是和JavaScript保持一致的,并且推荐较新的 let 和 const 代替 var .至于为什么这样做, ...
- [GO语言基础] 三.变量声明、数据类型、标识符及编程练习12题
作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Go的编译运行 ...
- python变量定义问题_python 定义n个变量方法 (变量声明自动化)
python 定义n个变量方法 (变量声明自动化) code: for i in range(100): cmd = "t%s = 1" % i exec cmd eval(&qu ...
- C++与Rust变量声明的比较
文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录) 对于变量声明,Rust默认不可变,需显式加mut关键字才可变.C/C++默认可变,不可变需加const关键字.严格意义上,Rus ...
- Java零基础系列003——变量
Java零基础系列003--变量 //变量(variable):程序中最基本的存储单元,包括变量名.类型.作用域 //变量应该先声明,只有声明后系统才会为其分配相应长度的存储空间,变量实质上就是存储单 ...
- Go 学习笔记(70)— Go 变量声明、变量初始化、值类型变量赋值、指针类型变量赋值
1. 变量声明 要单纯声明一个变量,可以通过 var 关键字,如下所示: var s string 该示例只是声明了一个变量 s,类型为 string,并没有对它进行初始化,所以它的值为 string ...
最新文章
- GPU上稀疏矩阵的基本线性代数
- raid5数据恢复成功案例
- springboot 主键重复导致数据重复_Springboot实现防重复提交和防重复点击(附源码)...
- 拒绝平庸--浅谈WEB登录页面设计
- spring mvc事务没有生效的原因
- Python安装selenium启动浏览器
- 前端学习(2573):vuex核心概念和底层原理
- Linux《命令行大全》——前言
- Linux下实现Raid 5软阵列
- 基于tensorflow+RNN的MNIST数据集手写数字分类
- 在MAC OS X下安装usb转串口驱动(PL2303主控芯片)
- 【C++】凯撒密码 实现加密与解密
- 模式识别--绪论 什么是模式识别?模式识别的主要方法及具体应用
- Python 离散小波变换(DWT) pywt库
- 女人假正经的十三种表现
- dcdc模块降额设计_爱默生网络能源PCB设计规范
- 餐厅预订系统有哪些?餐厅预订系统怎么选择?
- LTE下行传输机制——PHICH信道
- jmeter调试取样器
- 美的美少年计划(Java开发工程师)实习面经