1.枚举类型
枚举类型是用户自定义的类型,在定义时要列举出该枚举类型所有的数值。
定义格式如下:
[enum] enumName {val1, val2, val3}
- 其中的通常为较易懂的字符,这也是枚举类型的使用目的:增强易读性
- 按照顺序,枚举值依次与1,2,3等整数一一对应。在定义时也可以指出枚举值对应的数值,只是要指出的需要在左边,剩下未指出的的将会按照递增顺序。如:
enum Day {sun = 7, mon = 1, tue = 2, wed, thu, fri, sat}
2.数组
数组是一组组成元素类型相同的,在内存存储连续的序列。
dataType arrayName[memNum]
typedef
在用于数组定义时有种特殊的写法: typedef int A[10];
。这种写法将 int [10]
这样的数组定义作了 A
,其特殊之处在于新的名字夹在组成类型的中间
指在定义数组时,同时给出其值的表,格式为: int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
。
- 若使用初始化表而没有给出初值/给出的初值不够,则会用
0
作为其默认值进行补全 - 使用初始化表且完整给出所有值则可以省略数组定义时的个数:
int a[] = {1, 2, 3, 4, 5}
字符串数组是指形如 char s[num]
的数组。
所有的字符串数组在计算长度时都需要 -1
,因为要在末尾添加字符串的结束标志 \0
(新标准下数组长度似乎不再需要为结束标志留位置,且定义时给出的num下标即为最大可访问的下标)。在输出时会检测这个 \0
作为结束标志,而不会将这个标志输出,这种字符串叫 asciiz串
。
字符串数组可以用如下的方式进行初始化:
char s[] = {"hello"};
char s[] = {'h', 'e', 'l', 'l', 'o'};
char s[] = "hello"
这些方式都会在其末尾加上 \0
,而不需要考虑太多。若要求用户在运行时为字符串赋值,则要特别注意在用户输入后向末端添加 \0
。
格式: dataType arrayName[index1][index2];
,其中的index1对应行,index2对应列,可访问下标范围为 0-index1 - 1
, 0-index2 - 1
- 使用typedef来简化:
typedef int nickName[index1][index2];
- 可以用初始化表来为二维数组定义
-
int a [2][3] = {{2, 3}, {3, 4}}
:这样初始化后的二维数组对应为2, 3, 0; 3, 4, 0
,即是说可以用大括号内嵌套大括号的方式指定 -
在定义函数时若涉及二维数组的调用,则必须指明列数;行数可以通过用户传入的参数来界定,以此获得较灵活的使用。如:
int max (int array[ ][5], int row)
:这种方式定义的函数,可以传入所有列为5的二维数组,再通过传入的行参数即可访问该二维数组。即是说,定义参数时,必须指出列数,而行数可以省略(但必须通过其他方式指出,以防止越界)- 将二维数组作为一维数组使用
- 在逻辑上二维数组与现实生活情景有更加明确的关联,但是一二维数组在实现上没有本质差别,在内存中均为申请首地址后,一段连续的地址。
- 可以将二维数组传给调用参数为一维数组的函数,如:
- 有函数定义为
max(int x[ ], int max)
- 现有一二维数组
array[5][6]
- 则可以通过
max( array[0], 5*6)
来调用这个使用一维数组的函数
- 有函数定义为
3.结构类型
struct someName {
int val1;
char str[10];
};
//结合typedef完成定义
typedef struct someName{
int val1;
char str[10];
} newName;
newName a = {11, "hello"};
通过成员访问符 .
来调用其中的变量。如: a.val1
, a.str
4.联合类型
联合类型的定义与结构类似,但是联合定义的变量公用一块内存。即是说,一段时间内只能使用其中的一个变量类型,若同一时间要访问多个联合内的变量,会失败。
联合适用于一次性使用的、不在同一时间内使用的大变量,以来节省空间的使用。
union someName{
int a;
double b;
char c;
}
5.指针
dataType *pointerName
使用指针作为函数传递的参数,可以提高传输效率。常用在数组作为参数时使用。如:
int max(int *x, int num){
//形参为一个指针
.......;
}
int main(void){
int a [10];
....;
max(&a[0], 10);
//传回数组地址
}
这样避免了传递整个数组的低效。
使用指针,会有两个效果:
1. 提高参数传递的效率
2. 用形参改变了实参的值(调用的函数可能改变原有的、传入的实参的值)
而第二个效果常常会产生副作用,为了避免这个副作用,可以使用关键词 const
构成 指针常量
。 指针常量
只能改变所指向的内存(即地址值),但不能通过间接访问改变所指向内存的数值(指地址所指向的内容)。这样就避免了形参改变实参,同时还保留了传递参数的功能。
指针常量
的声明: dataType *const pointerName
即是在 *
前加了关键词 const
以申明指针常量。
需要与 指针常量
区别的是 指向常量的指针常量
指向常量的指针常量
是一个常量,即不能改变它指向的值,也不能通过间接访问改变它所指向的内存。
指向常量的指针常量
的声明: const dataType *const pointerName
在指针常量前也加上关键词 const
,就构成了指向常量的指针常量。
指针常量: dataType *const pointerName
指向常量的指针常量: const dataType *const pointerName
6.动态变量
动态变量是指,在程序在静态的未运行阶段无法确定的变量,只有在程序运行时他才根据程序的需要产生、消亡。
动态变量的申请有两种方式
int *p;
p = new int;
*p = 1;
int *p;
int n;
//一维数组
p = new int[n];
//二维数组
p = new int[n][20];
//应当注意高维数目一定得指定,最低一维可以不指定
int *p;
p = (int *)malloc(sizeof(int) );
int *p;
p = (int *)malloc(sizeof(int) *n);
//申请了一个一维数组,可以放(0,n-1)个数
p = (int *)malloc(sizeof(int) *n * 20);
//申请了一个二维数组,且同上:高维必须指出,低维可以不指出
主要在于:
使用 new
创建的变量最好使用关键字 delete
销毁
格式: delete pointerName
//销毁单个动态变量
delete p;
//销毁指向动态数组的变量
delete [ ]p;
使用 malloc()
创建的变量最好使用函数 free()
销毁
格式: free(pointerName)
//free( )因为是函数,所以只有一种使用方法,而没有多种格式
free(p);
主要区别如下:
当一个指向动态变量的指针改变指向的变量后,便无法完成对动态变量的访问了,无法对其访问也无法回收对之分配的内存,这种现象叫做 内存泄漏
7.函数指针
dataType (* pointerName)(argsType)
有两种格式,如下方演示
int (* fp)(int, double);
int demo(int a, double b){
return a;
}
//方法1
fp = demo;
//方法2
fp = &demo;
这里调用即是指用 函数指针
完成对函数的调用,也是 函数指针的用处
。调用也有两种格式
int (* fp)(int, double);
int demo(int a, double b);
//方法1
(*fp)(10, 2.8);
//方法2
fp(10, 2.9);
Original: https://www.cnblogs.com/dysonxxxxx/p/16582081.html
Author: dysonkkk
Title: cpp-变量
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/578834/
转载文章受原作者版权保护。转载请注明原作者出处!