关键字register static const #define用法总结

打卡:4.21 C语言篇 -(1)初识C语言 - (11)关键字register,#define定义的宏 关键字register,#define定义的宏 阅读详情

关键字registe请求编译器尽可能的将变量存在CPU的寄存器中。有以下几点注意的地方。

对register的使用是有限制条件的,这个体现在具体硬件上。

每个函数中只有很少的变量能够存放在寄存器中,而且,只是确定的类型可以存放在寄存器中。过多的使用寄存器变量并没有坏处,然而,由于“register”会被忽略的。

特别注意:不能用&取地址符号,去获取一个register变量的地址,无论这个变量是否被实际得存放在寄存器里了

register变量必须是能被CPU寄存器所接受的类型,这通常意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度。但是,有些机器的寄存器也能存放浮点数。

register变量可能不存放在内存中,所以不能用取址符运算符“ & ”。

只有局部变量和形参可以作为register变量,全局变量不行。

静态变量不能定义为register。

 

 

static用法小结

static关键字是C, C++中都存在的关键字, 它主要有三种使用方式, 其中前两种只指在C语言中使用, 第三种在C++中使用(C,C++中具体细微操作不尽相同, 本文以C++为准).
(1)局部静态变量
(2)外部静态变量/函数
(3)静态数据成员/成员函数
下面就这三种使用方式及注意事项分别说明

一、局部静态变量
在C/C++中, 局部变量按照存储形式可分为三种auto, static, register
(<c语言程序设计(第二版)>谭浩强, 第174-175页)
与auto类型(普通)局部变量相比, static局部变量有三点不同
1. 存储空间分配不同
auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同.
2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次
3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的. (对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型)

特点: static局部变量的”记忆性”与生存期的”全局性”
所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值.
示例程序一
#include <iostream>

using namespace std;

void staticLocalVar()
{
 static int a = 0; // 运行期时初始化一次, 下次再调用时, 不进行初始化工作
 cout<<"a="<<a<<endl;
 ++a;
}

int main()
{
 staticLocalVar(); // 第一次调用, 输出a=0
 staticLocalVar(); // 第二次调用, 记忆了第一次退出时的值, 输出a=1
 return 0;
}

应用:
 利用”记忆性”, 记录函数调用的次数(示例程序一)
   利用生存期的”全局性”, 改善”return a pointer / reference to a local object”的问题. Local object的问题在于退出函数, 生存期即结束,. 利用static的作用, 延长变量的生存期.
示例程序二:
// IP address to string format
// Used in Ethernet Frame and IP Header analysis
const char * IpToStr(UINT32 IpAddr)
{
 static char strBuff[16]; // static局部变量, 用于返回地址有效
 const unsigned char *pChIP = (const unsigned char *)&IpAddr;
 sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);
 return strBuff;
}

注意事项:
1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同.
2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题 ---- 不可重入性!!!
这样在多线程程序设计或递归程序设计中, 要特别注意这个问题.
(不可重入性的例子可以参见<effective C++ (2nd)>(影印版)第103-105页)
下面针对示例程序二, 分析在多线程情况下的不安全性.(为方便描述, 标上行号)
① const char * IpToStr(UINT32 IpAddr)
② {
③  static char strBuff[16]; // static局部变量, 用于返回地址有效
④  const unsigned char *pChIP = (const unsigned char *)&IpAddr;
⑤  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);
⑥  return strBuff;
⑦ }
假设现在有两个线程A,B运行期间都需要调用IpToStr()函数, 将32位的IP地址转换成点分10进制的字符串形式. 现A先获得执行机会, 执行IpToStr(), 传入的参数是0x0B090A0A, 顺序执行完应该返回的指针存储区内容是:”10.10.9.11”, 现执行到⑥时, 失去执行权, 调度到B线程执行, B线程传入的参数是0xA8A8A8C0, 执行至⑦, 静态存储区的内容是192.168.168.168. 当再调度到A执行时, 从⑥继续执行, 由于strBuff的全局唯一性, 内容已经被B线程冲掉, 此时返回的将是192.168.168.168字符串, 不再是10.10.9.11字符串.

二、外部静态变量/函数
在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
示例程序三:
 
//file1.cpp

static int varA;
int varB;
extern void funA()
{
……
}

static void funB()
{
……
}

//file2.cpp

extern int varB; // 使用file1.cpp中定义的全局变量
extern int varA; // 错误! varA是static类型, 无法在其他文件中使用
extern vod funA(); // 使用file1.cpp中定义的函数
extern void funB(); // 错误! 无法使用file1.cpp文件中static函数

 

三、静态数据成员/成员函数(C++特有)
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. )
请看示例程序四(<effective c++ (2nd)>(影印版)第59页)
class EnemyTarget {
public:
  EnemyTarget() { ++numTargets; }
  EnemyTarget(const EnemyTarget&) { ++numTargets; }
  ~EnemyTarget() { --numTargets; }
  static size_t numberOfTargets() { return numTargets; }
  bool destroy();   // returns success of attempt to destroy EnemyTarget object
private:
  static size_t numTargets;               // object counter
};
// class statics must be defined outside the class;
// initialization is to 0 by default
size_t EnemyTarget::numTargets;

在这个例子中, 静态数据成员numTargets就是用来计数产生的对象个数的.
另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数.

 

 

const用法主要是防止定义的对象再次被修改,定义对象变量时要初始化变量

 

下面我就介绍一下几种常见的用法

1.用于定义常量变量,这样这个变量在后面就不可以再被修改

 const int Val = 10;

 //Val = 20; //错误,不可被修改

 

2. 保护传参时参数不被修改,如果使用引用传递参数或按地址传递参数给一个函数,在这个函数里这个参数的值若被修改,

则函数外部传进来的变量的值也发生改变,若想保护传进来的变量不被修改,可以使用const保护

 void  fun1(const int &val)

  {

     //val = 10; //出错

}

void fun2(int &val)

{

   val = 10; //没有出错

}

void main()

{

   int a = 2;

   int b = 2;

   fun1(a); //因为出错,这个函数结束时a的值还是2

   fun2(b);//因为没有出错,函数结束时b的值为10

}

如果只想把值传给函数,而且这个不能被修改,则可以使用const保护变量,有人会问为什么不按值传递,按值传递还需要把这个值复制一遍,

而引用不需要,使用引用是为了提高效率//如果按值传递的话,没必要加const,那样根本没意义

 

3. 节约内存空间,

 #define  PI  3.14 //使用#define宏

 const double Pi = 3.14 //使用const,这时候Pi并没有放入内存中

 

 double  a = Pi;  //这时候才为Pi分配内存,不过后面再有这样的定义也不会再分配内存

 double  b = PI;  //编译时分配内存

 double  c = Pi;  //不会再分配内存,

 double  d = PI;  //编译时再分配内存

const定义的变量,系统只为它分配一次内存,而使用#define定义的常量宏,能分配好多次,这样const就很节约空间

 

4.类中使用const修饰函数防止修改非static类成员变量

 class

{

 public:

  void fun() const //加const修饰

   {

     a = 10; //出错,不可修改非static变量

     b = 10; //对,可以修改

}

 private:

  int  a ;

  static int b;

}

 

5.修饰指针
const int *A; 或 int const *A;  //const修饰指向的对象,A可变,A指向的对象不可变
int *const A;               //const修饰指针A, A不可变,A指向的对象可变
const int *const A;           //指针A和A指向的对象都不可变

 

 

6.修饰函数返回值,防止返回值被改变

  const int fun();

  接收返回值的变量也必须加const

  const int a = fun(); //接收的变量也要是const的,int a = fun()是错误的

 

7.修饰类的成员变量

  使用const修饰的变量必须初始化,在类中又不能在定义时初始化,

如;

class

{

private:

  int a = 10;

  const int b = 10;

  static const int c = 10;

//这样初始化都是错的,

}

 

初始化const int类型(没有static),在类的构造函数上初始化

Class Test

{

Public:

  Test():b(23) //构造函数上初始化b的值为23

   {

}

private:

     const int b ;

}

 

初始化staticconst int这个类型的(带有static的),在类的外面初始化

class Test

{

private:

  static const int c;

} 

const int Test::c=10; //类的外部初始化c为10

 

8.const定义的对象变量只能作用于这个程序该C/C++文件,不能被该程序的其他C/C++文件调用,

 如file1.cpp中 const int val;

 在file2.cpp中, extern intval; //错误,无法调用,

要想const定义的对象变量能被其他文件调用,定义时必须使用extern修饰为

extern const int val;

 

非const变量默认为extern,要是const能被其他文件访问必须显示指定为extern

 

 

 

先来讲一讲#define的优点与缺点:
[优点]

当在程序中想要修改某一个值得时候,而且这个值又在很多地方引用。这时候就能体现出宏定义的强大优点了。
例如:

#define LINK LED0   //定义LINK的灯为LED0
  • 1

因为在程序中我们可能很多地方要对LINK灯进行操作,当我们想换LINK灯的时候,直接将:

#define LINK LED1
  • 1

这样就很方便了,不用一处处去找,而且不用担心有漏掉的可能。
[缺点]
宏定义有一些缺点:
(1) 无法对宏定义中的变量进行类型检查
此缺点,是相对于const变量来说的

[define与const的区别的简单总结]

define定义的变量,是Compile-Time时期的变量,系统在编译时候,就将其全部替换,而不会对其变量进行类型等属性检查,相对不是很安全,可能存在潜在的问题,而没有发现.
正因为其仅仅是编译时期替换,所以其定义的变量,是不会在运行时候分配内存的,不占用内存空间.
const定义的变量,是 Run-Time时期的变量,如果类型不匹配,系统在运行时候,就会发现并提示或报错,对应的,const变量在运行时期,也是一种变量,系统会为其分配内存.
(2) 边界效应
A. 未加括号带来的边界效应
由于宏定义的时候,其各个分量未加括号,而在使用宏定义的时候,传递的参数是变量的表达式,然后经过系统展开后,由于优先级的原因,导致其结果不是你所希望的.
[例子]

 

#define MUL(A,B) A*B
  • 1

 

而在使用的时候,这样的调用:
int a=1,b=2,c=3,d=0;
d=MUL(a+b,c)
经过编译时候展开,就变成了
d=a+b*c
而不是我们所希望的
d=(a+b)*c
[解决办法]
其解决办法也很简单,就是给每个分量,都加上括号,就可以避免此类问题
即,在宏定义的时候,如此定义:

#define MUL(A,B) ((A)*(B))
  • 1
  1. #define的变体,即#ifndef,可以防止头头文件的重复引用
    [释]
    #ifdef和 #define组合,一般用于头文件中,用以实现防止多个文件对此同一个头文件的重复引用.实际使用中,即使你的头文件暂时没有被多个文件所引用,为了增加程序可读性,移植性,健壮性等,还是最好都加上。其用法一般为:
#ifndef <</SPAN>标识>
#define <</SPAN>标识>
………   // include or define sth.
#endif
  • 1
  • 2
  • 3
  • 4

<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的;标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,
如:stdio.h对应的就是:

#ifndef _STDIO_H_
#define _STDIO_H_
………   // include or define sth.
#endif
  • 1
  • 2
  • 3
  • 4

举个例子:

 

#ifndef CHARDEV_H
#define CHARDEV_H

#include


#define MAJOR_NUM 100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

 

……

……

#endif

例子中的chardev.h中,就用到了

#ifndef CHARDEV_H
#define CHARDEV_H
…
#endif
  • 1
  • 2
  • 3
  • 4

这样做之后,以后某个文件引用此头文件,就包含了chardev.h文件,而其他文件如果再引用此头文件的话,编译器那么就会判断出来,已经define了CHARDEV_H,已经有其他文件引用了此文件,so,the complier will not include this header file. 就可以发现解决重复引用头文件的问题了.

2. #define的变体,即#ifdef,可以实现加入自己需要的模块(源文件)
[例子]
在源文件中加入

#ifdef MYSELF_H
#include "myself.c"
#endif
  • 1
  • 2
  • 3

可以实现在源文件中加入myself.c的代码,将其实现的功能加进来, 即加入了myself模块
3. 简单的define定义

#define MAXTIME 1000
  • 1

一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写

 

if(i<MAXTIME){.........}
  • 1

 

编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。

这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。
4. define的“函数定义”
define可以像函数那样接受一些参数,如下

#define max(x,y) (x)>(y)?(x):(y);
  • 1

这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。

但是这样做的话存在隐患,例子如下:

#define Add(a,b) a+b;
  • 1

在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了

c*a + b*d
  • 1

另外举一个例子:

#define pin (int*);
  • 1
pin a,b;
  • 1

本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。

这是应该使用typedef来代替define,这样a和b就都是int型指针了。
即:

typedef pin (int *)

pin a,b;
  • 1
  • 2
  • 3

 

此时:a和b都是 int*型的。
所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。
5. 宏的单行定义

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x
  • 1
  • 2
  • 3

我们假设:x=1,则有:

A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"
  • 1
  • 2
  • 3

6. define的多行定义

define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心)

#define MACRO(arg1, arg2) do { /
/* declarations */ /
stmt1; /
stmt2; /
/* ... */ /
} while(0) /* (no trailing ; ) */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

关键是要在每一个换行的时候加上一个”/”

7 .在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

即:

 

#ifdef WINDOWS
......
......
#endif
#ifdef LINUX
......
......
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

 

可以在编译的时候通过#define设置编译环境

8. 如何定义宏、取消宏

//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
//普通宏
#define PI (3.1415926)

带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

关键是十分容易产生错误,包括机器和人理解上的差异等等。

9. 条件编译

#ifdef XXX…(#else) … #endif
例如
#ifdef DV22_AUX_INPUT
#define AUX_MODE 3 
#else
#define AUY_MODE 3
#endif
#ifndef XXX … (#else) … #endif

 

 

 

 

 

 

 

 

 

C++:C++编程语言学习之数据类型&常量&变量的简介、案例应用之详细攻略 ​ C++:C++编程语言学习之数据类型&常量&变量的简介、案例应用之详细攻略 目录 1、C++语言的数据类型 2、C++语言的常量 3、C++语言的变量 1、C++语言的数据类型 1.1、C++语言的七种基本数据类型 (1)、变量的大小会根据编译器和所使用的电脑而有所不同。 布尔型bool、字符型char、整型int、浮点型float、双浮点型double 、无类型void、宽字符型wchar_t 1.2、C++语言的其他类型 也允许定义各种其他类型的变量,比如枚举、 阅读详情

相关推荐

Python+OpenCV实战:雨天车牌识别准确率提升300%的5个关键技巧

本文针对雨天车牌识别准确率骤降的难题,分享了五个基于Python和OpenCV的实战技巧。通过暗通道先验去雾、雨纹抑制、光照不变量颜色空间转换、多尺度自适应阈值分割以及融合传统特征与轻量级深度学习的混合识别策略,系统性地提升了算法在恶劣天气下的鲁棒性。这些方法能有效解决图像模糊、对比度低、字符断裂粘连等问题,为智能交通等实际应用提供可靠解决方案。

k8l9m0n的博客 716

c++宏定义中#作用、逗号表达式

最近看到一位同事写的代码,遇到一个语句,不知道什么意思,随查了一下,记录如下

wenliang1314的博客 2072

告别Selenium!纯Python+Requests搞定微信视频号登录Cookie(附完整代码与避坑指南)

本文详细介绍了如何利用纯Python和Requests库实现微信视频号的自动化登录,替代传统的Selenium方案。通过解析HTTP请求交互流程,提供完整的代码实现和避坑指南,显著提升爬虫效率和隐蔽性,适用于轻量化爬虫开发。

weixin_30642561的博客 312

#define REGISTER(NAME)

#define REGISTER(NAME) 偶遇一次一个结构体被定义并且初始化了,然后感觉没有被用到的样子,就觉得奇怪了,后来找了找才发现用 宏定义的一个操作,通过函数调用来完成初始化的。写下来留作笔记O(∩_∩)O #include typedef struct data_handler{ int m_product_type; struct data_handler *next;

huangxinfeng_的博客 1321

SD-WAN组网案例——数据中心

SD-WAN组网案例——数据中心

2301_78457663的博客 706

学习 Bootstrap 5 之 Tables

学习 Bootstrap 5 之 表格表格 (Tables)1. 创建表格(1). 使用原生的表格标签(2). 使用Bootstrap 5 的提供的表格标签类(3). 原生与Bootstrap创建出来的表格的对比2. 表格样式(1). 表格样式的效果(2). 表格样式的使用1). 用于 <table> 标签2). 用于 <thead> <tbody> <tfoot> 标签 表格 (Tables) 1. 创建表格 (1). 使用原生的表格标签 <tabl

qq_37354060的博客 2130

register 寄存器变量

1.寄存器变量可以用来优化加速c语言程序 2.声名只需在类型前多加register 当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的...

1900的博客 1144

Unity GameObject 核心机制深度解析:从底层结构到工程实践

从底层机制讲透 Unity GameObject:托管壳加原生芯的双层对象模型如何制造假 null 陷阱、Transform 层级与组件通信的原理、生命周期回调的确切顺序。文章同时给出 Instantiate 成本分析与对象池等高频场景的工程实践。

游戏人生 40

#define

define的用途(1)在#define name stuff这条指令中,在程序中每当出现name时,预处理器就会把它自动替换成stuff。替换文本并不仅限于数值字面常量,可以是任何文本。 #define reg register //为register这个关键字创建一个简短的名字 #define CASE break;case //以便在写case语句时候自动把break写

985136449的博客 1759

【三维激光扫描】第二章:国内外三维激光扫描设备简介

地面三维激光扫描仪是地面激光扫描系统中最主要的硬件设备,近年来得到了快速发展,主要体现在品牌数量、性能指标、类型等方面的变化。本章主要介绍国内外主要设备的基本情况,对国内外研究现状进行分析,最后指出目前存在的问题与未来的发展趋势。 2.1 国外地面三维激光扫描仪简介 目前,生产地面三维激光扫描仪的公司比较多,随着地面三维激光扫描技术应用普及程度的不断提高,国外产品在中国的市场目前还占主导地位。它们各自的产品在性能指标上有所不同,以下简要介绍有代表性的公司产品。 2.1.1 奥地利 Riegl公司的.

智慧空间实验室 4642

Python与CAD系列基础篇(十)图形复制、移动、删除

①通过pyautocad连接AutoCAD进行处理②通过ezdxf处理dxf格式文件。进行图形复制、移动、删除的方法。pyautocad方式。pyautocad方式。

weixin_43894929的博客 2210

C语言经典关键字

C语言关键字

future_sky_word的博客 734

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

关键字结构体的介绍以及typede与define的区别

register关键字 1、作用:请求编译器尽量将变量保存在CPU内部寄存器里,可以省去CPU从内存中抓取数据的时间,从而提高运行效率 2、我们可以将频繁使用的变量修饰为register变量 3、register使用注意点:①register只能修饰局部变量,不能修饰全局变量(因为全局变量被多个进程访问,如果当前进程将变量修饰为register,其他进程去不知道,从而不能修饰局部

fighting_kangle的博客 1843

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【嵌入式Linux C编程】2018.3.9 C语言中的常用关键字

C语言中常用关键字static 与 externstatic修饰变量时,该变量的存储空间转移到静态数据存储区。一般情况下局部变量时存放在栈区的,并且其声明周期是在该语句块执行结束时便结束了。但如果用static修饰,该变量便存放在静态数据区,其生命周期一直延续到整个程序结束为止,但是其作用域并没有发生变化,依旧只作用于该语句块。对于静态的局部变量,如果没有进行初始化,它会继承之前最后一次赋予它的值...

qq_39612543的博客 225

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C语言复习笔记(二)- C语言关键字详解

C语言校招复习笔记系列(二)关键字类型说明保留字功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 关键字 C语言的关键字...

wanglizhi3733的博客 472

各种关键字

什么是数据类型?1.固定内存大小的别名2.创建变量的模子变量本质?1.变量是一段实际连续存储空间的别名2.程序中通过变量来申请并命名存储空间3.通过变量的名字可以使用存储空间自定义类型,通过typedef定义,其实就是相当于换了个别名创建变量,格式:类型名 变量名;

qq_51712982的博客 868

阐述C语言

阐述C语言 C语言关键字详解阐述C语言欢迎使用C语言编写程序32个关键字typedef和#define的区别关键字解释注释也是必不可少的 欢迎使用C语言编写程序 在这里先普及一下,在我们C语言中一共有32个关键字,可能有几个在我们学习的过程中不太常用,但是大多数都是我们常用的,下来我们先来罗列一下着32个关键字都有什么,再来一一说一下他们的用法: 说关键字之前,先声明两个概念,在后面的文章中会用到...

171207的博客 275

C:关键字

定义只读变量的关键字,常变量的关键字。不会因编译器的优化而省略,且要求每次直接读值,变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值。定义数据类型新名字,是存储类的关键字,与 auto、extern、static、register 等关键字不能出现在同一个表达式中。1.寄存器变量类型是CPU接受的类型,寄存器变量长度应该小于等于寄存器长度。可以被所有函数访问,不能被其它文件内的函数访问。寄存器变量是变量直接引用寄存器,变量名的操作的结果是直接对寄存器进行访问。

tyro_wzp的博客 138

2021-05-26 C语言关键字全集

C语言关键字全集 1、Register 关键字 该关键字声明某个变量时,请求编译器尽可能将该变量存储在CPU内部的寄存器中而不是内存中,以提高速率。是尽可能,不是绝对的,因为寄存器的数量是有限的,只有这么几十个。 虽然寄存器的速度非常快,但是使用register 修饰符也有些限制的:register 变量必须是能被CPU 寄存器所接受的类型。意味着register 变量必须是一个单个的值,并且其长度应小于或等于整型的长度。而且register 变量可能不存放在内存中,所以不能用取址运算符“&”来获

qq799703655的博客 358

类c语言常量信息表,C语言笔记 03_常量&存储类

常量常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。整数常量整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0x 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。整数常量也可以带一个后缀,后缀是 u 和 l 的组合,u 表示无符号整数(unsigned),l...

weixin_28884611的博客 253

零基础快乐学习C/C++——03

1.常见关键字 熟知常见的关键字可以避免在定义变量时误用 auto 局部变量通常前面省略了auto 如下 int main(){ auto int a = 10;//通常来讲省略了auto 局部变量及自动变量 return 0; } const break case default do double extern(引入外部符号) float for goto if int long void union(联合体) volatile while sizeof register(寄存器关键字) 举

weixin_44062400的博客 249

C语言-static关键词,寄存器变量,define宏定义

本文介绍了C语言中static关键字的三种用法:修饰局部变量时使变量生命周期延长;修饰全局变量和函数时限制其作用域仅限当前文件。此外还介绍了寄存器变量和宏定义的使用:register建议编译器将变量存储在寄存器中;#define可定义常量和带参数的宏。这些特性可用于优化程序性能和实现代码封装。

m0_53123717的博客 125

17.C语言 常见面试题

嵌入式工程师必备0x10到题目 宏定义 1.用预处理指令#define声明一个常数,用于表明1年中有多少秒 #define 宏名 宏体 宏名:大写字母表示 #define SECOND_OF_YEAR (365*24*3600) int的常量 数据声明 修饰符的使用总结 类型修饰符 auto、register、static、const、extern、volatile 对内存资源存放位置的限定 资源属性中位置的限定 修饰符的使用总结 关键字static的作用..

m0_57908316的博客 428

C语言和数据结构与算法(99)

typedef更好,因为这种方式更直接,更易读,更具有可维护性,#define的方式更容易出现副作用,看例子1,在下面代码中,使用了#define和typedef定义了两个指向结构体s的指针类型p1和p2,其中p2没有使用#define,如果使用#define宏定义的方式,预处理会将所有的dPS替换为struct s *,这样就会导致p1和p2的大小不一致。第二行代码正确的定义了p3和p4两个指针。由于*ptr指向的值可能会被意想不到的改变,所以a和b的值可能不一样,所以这个函数是有问题的。

m0_56668471的博客 473

学习日记之c语言易错易考点1

1,a++、++a a++ 先赋值再自增 ++a 先自增后赋值 使用以下代码区分两者的区别: int main() { //可以理解成 ++a 是先自增后使用 int a = 8; int b = ++a; printf("a = %d b = %d\n", a, b);//9 9 // a++ 是先使用后自增 a = 10; b = a++; printf("a = %d b = %d\n", a, b);//9 8 return 0; } i.

Doublestarpro的博客 1660
上一篇: Linux:chmod命令用法
下一篇: 普通用户find 排除权限不够的方法
StudyTaoo
博客等级 码龄11年 128粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值