C语言学习笔记 1.变量(const define enum)

C语言 变量

一.const

被 const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

1.const 使用

使用const修饰变量必须初始化

用 const 修饰的变量,无论是全局变量还是局部变量,生存周期都是程序运行的整个过程。

而使用 const 修饰过的局部变量就有了静态特性,它的生存周期也是程序运行的整个过程。

但是用 const 修饰过的局部变量只是有了静态特性,并没有说它变成了静态变量。

2.const 修饰指针

a.指针

int *p = 5;

/*p:指针的内存地址,类似门牌号,十六进制表示:0xffff
 
*p:指针的内存地址对应的值,类似门牌号对应里面住的人,即5
*/

b.const int *p & int const *p

const int *p 和 int const *p是等价的

当把 const 放最前面的时候,它修饰的就是 *p,那么 *p 就不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,此时这个内容不可变 。

其他的都可变,如 p 中存放的是指向的内存单元的地址,这个地址可变,即 p 的指向可变。但指向谁,谁的内容就不可变。

# include <stdio.h>
int main(void)
{
    int a = 10;
    const int *p = &a;
    int * q = &a;
    *q = 20;
    printf("a = %d\n", a);
    a = 30;
    printf("a = %d\n", a);
    //const int *p = &a; //表示 *p 值不能发生改变否则 error: assignment of read-only location '* p'
    //*p = 30;  //这么写就是错的
     return 0;
}
/*
 输出:a = 20
 a = 30
*/

c.int * const p

此时 const 修饰的是 p,所以 p 中存放的内存单元的地址不可变,而内存单元中的内容可变。即 p 的指向不可变,p 所指向的内存单元的内容可变。

# include <stdio.h>
int main(void)
{
    const char *p = "hello"; //(*p)值不变,但p代表的起始地址可变
    char* const q = "bbb"; //q地址不能改变(即q值不变)
    p++;   //ok
    //q++; //这句是错误的. error: increment of read-only variable 'q'
    printf("%s\n",p);
    printf("%s\n",q);
    return 0;
}
/*
 输出:
ello
bbb
*/

d. const int * const p

*p 和 p 都被修饰了,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变。

3.const 修饰在函数名前面

当 const 在函数名前面的时候修饰的是函数返回值;在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能读操作,不能写操作。

const char * GetString(void);
const double GetDdouble(void);

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针;

const char * GetString(void);
//如下语句将出现编译错误:
//char *str = GetString();
//正确的用法是
const char  *str = GetString();

4.const 修饰在函数名后面

当 const 在函数名前面的时候修饰的是函数返回值;在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。

5.const 修饰函数参数

如果函数参数采用“指针传递”,那么加 const 修饰可以防止意外地改动该指针,起到保护作用。

void StringCopy (char*strDestination, const char *strSource);

其中 strSource 是输入参数,strDestination 是输出参数。给 strSource 加上 const 修饰后,如果函数体内的语句试图改动 strSource 的内容,编译器将指出错误。

如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加 const 修饰。

例如不要将函数 void Func1(int x) 写成 void Func1(const int x)。

如果参数作为输出参数,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。

如果参数作为输入参数,可以防止数据被改变,起到保护作用,增加程序的健壮性;

二. define

1.define用法

//定义常量
#define MAX_VALUE 100       //定义整型变量MAX_VALUE值为100
#define USER_NAME "huge"    //定义字符串变量USER_NAME值为"huge"
#define PI 3.1415926        //定义浮点数变量PI值为3.1415926

//定义函数
#define MAX(a,b) (a>b)?a:b  //取两个数最大值
#define MIN(a,b) (a<b)?a:b  //取两个数最小值

2.const比define的优点

const 可节省空间,避免不必要的内存分配,提高效率

三. 枚举常量enum

1.赋值

#include <stdio.h>
enum color
{
	red,
	green,
	yellow
};
int main()
{
	printf("%d\n", red);   //0
	printf("%d\n", green); //1
	printf("%d\n", yellow);//2
	return 0;
}

但是我们又需要注意,如果只给其中一个枚举常量赋值,但是后面的值没有被赋予。那么后的常量会根据被赋予值开始,依次递增。而被赋值前的值从0开始递增。

#include <stdio.h>
enum color
{
	red,
	black,
	green = 4,
	yellow
};
 
int main()
{
	printf("%d\n", red);    //0,被赋予值之前的从0开始递增
    printf("%d\n", black);  //1
	printf("%d\n", green);  //4,被赋予值之后,从赋予值开始递增
	printf("%d\n", yellow); //5
	return 0;
}

2.使用

有了枚举常量之后,我们可以这样使用。这样能够方便的得知我所选择的颜色是什么,并且根据所选的颜色进行相对应的操作。

#include <stdio.h>
enum color
{
	red,
	green,
	yellow
};
int main()
{
	int Select_color = red;
	if (Select_color == red)
	{
		printf("red\n");
	}
	if (Select_color == green)
	{
		printf("green\n");
	}
	if (Select_color == yellow)
	{
		printf("yellow\n");
	}
	return 0;
}

3.应用

看下面图片,我们有一个IE中断运行寄存器。从最低位B0到最高位B7,有七个bit位。每一位表示进行一个操作,很明显我们难以记下来。那怎么办呢?枚举就是最好的办法

在这里插入图片描述
如下为枚举之后的代码。很明显,如果我们想打开寄存器中的某一个位,就不需要再去看数据手册了,直接根据这个枚举就很轻松的可以随意操作。

#include <stdio.h>
enum IE
{
	EX0    = 0x01,//0000 0001
	ET0    = 0x02,//0000 0010
	EX1    = 0x04,//0000 0100
	ET1    = 0x08,//0000 1000
	ES     = 0x10,//0001 0000
	ET2    = 0x20,//0010 0000
	Retain = 0x40,//0100 0000
	EA     = 0x80 //1000 0000
};
 
 
 
int main()
{
	int Select_IE = EX0;
	if (Select_IE == EX0)
	{
		printf("EX0\n");
	}
	if (Select_IE == ET0)
	{
		printf("ET0\n");
	}
	if (Select_IE == EX1)
	{
		printf("EX1\n");
	}
	return 0;
}

4.注意

不能给枚举常量赋值是说,不能再enum外给枚举常量赋值。

#include <stdio.h>
enum IE
{
	EX0    = 0x01,//0000 0001
	ET0    = 0x02,//0000 0010
	EX1    = 0x04,//0000 0100
	ET1    = 0x08,//0000 1000
	ES     = 0x10,//0001 0000
	ET2    = 0x20,//0010 0000
	Retain = 0x40,//0100 0000
	EA     = 0x80 //1000 0000
};
 
 
 
int main()
{
	EX0 = 30;  //报错,表达式必须是可修改的左值
    int Select_IE = EX0;  //可以,枚举常量的值可以赋予其他变量
	return 0;
}

原文转载:

https://blog.csdn.net/ZhaDeNianQu/article/details/120195045
https://blog.csdn.net/qq_63922192/article/details/127324040

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值