C语言关键字

C语言 string 关键字

2019-08-31 18:45:41

由ASCII标准定义的C语言关键字共32个:

数据关键字12个:char,double,float,enum,float,int,long,short,signed,struct,union,void

控制语句关键字12个:for,do,while,break,continue,if,else,goto,switch,case,default,return

存储类型关键字4个:auto,extern,regsiter,static

其他关键字4个:const,sizeof,typedef,volatile

一、数据关键字

1、 char :声明字符型变量或函数
2、short :声明短整型变量或函数
3、 int: 声明整型变量或函数
4、 long :声明长整型变量或函数
5、float:声明浮点型变量或函数
6、double :声明双精度变量或函数
7、enum :声明枚举类型

enum weekday{sun,mon,tue,wed,thu,fri,sat}; //枚举元素从零开始,定义为0,1,2,...。sun的值是0,sta的值是6。
 
enum weekday a,b,c;
a=(enum weekday)2; //只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。如果一定要把数值赋予枚举变量,则必须使用强制类型转换。

8、signed:声明有符号类型变量或函数
9、unsigned:声明无符号类型变量或函数
10、struct:声明结构体变量或函数

struct student
{
    int num;
    char name[20];
    char sex;
    float score;
}; //注意结尾的分号

11、union:声明共用体(联合)数据类型

union foo{
    int i;
    char c;
    double k;
}; //注意最后的分号不要忘记

12、void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)

void getNothingFromFunc(); //作用一: 对函数返回的限定,函数无返回值
int function(void); //作用二:对函数参数的限定,函数没有入参
 
void* memcpy(void* dest, const void* src, size_t len); //如果函数的参数可以是任意类型指针,那么应声明其参数为void *

二、存储类型关键字

1、auto

这个关键字在C语言中用于声名变量,即将在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变量默认就是auto的。

auto double a=3.7; //表示a为一个自动存储的临时变量。
在C++11标准的语法中,auto被定义为自动推断变量的类型。

auto x = 5.2;//这里的x被auto推断为double类型

不过C++11的auto关键字时有一个限定条件,那就是必须给申明的变量赋予一个初始值,否则编译器在编译阶段将会报错。

适用的场景:
(1)一些类型长度书写很长的,可以使用 auto 来简化,如 for(std::vector<int>::iterator it = v.begin();it != v.end();++it),如果使用 auto 可以直接写为 for(auto it = v.begin();it != v.end();++it)
(2)当函数返回的值不确定时,可以使用 auto 做返回值类型,更加方便,
	编译器会根据返回值的类型推断 auto 的类型,这种语法是在 C++14 才出现的。
auto func()        // 这种写法在 C++14 是允许的

{
        return 0;   
}

不适用的场景
(1) 函数参数类型不能是 auto 类型,比如 int add(auto a, auto b) { return a + b; } 是不允许的
(2) 类的成员变量不可以是 auto 类型。类的静态成员变量可以是 auto 类型的,
	但是需要使用 const 修饰,而且该变量的值在类内初始化

2、extern

①、引用同一个文件的变量(主要为了使用在后面定义的变量)

#include<stdio.h>
int func();
int main()
{
    func(); //1
    extern int num;
    printf("%d",num); //2
    return 0;
}
int num = 3;
int func()
{
    printf("%d\n",num);
}

②、引用另一个文件中的变量
   main.c

#include<stdio.h>

int main()
{
    extern int num;
    printf("%d",num);
    return 0;
}

   b.c

#include<stdio.h>

int num = 5;

void func()
{
    printf("fun in a.c");
}

注意:
  1、只有当一个变量是一个全局变量时,extern变量才会起作用。
  2、extern关键字只需要指明类型和变量名就行了,不能再重新赋值,初始化需要在原文件所在处进行,如果不 进行初始化的话,全局变量会被编译器自动初始化为0。
  3、还可以使用 const进行修饰,例如extern const int num
  4、使用include将另一个文件全部包含进去也可以引用另一个文件中的变量,但是这样做的结果就是,被包含的文件中的所有的变量和方法都可以被这个文件使用,这样就变得不安全,如果只是希望一个文件使用另一个文件中的某个变量还是使用extern关键字更好。

③、引用另一个文件中的函数,引用方法和引用变量相似。

④、extern修饰符可用于指示C或者C++函数的调用规范。
  例如:extern "C"

3、register

  声名寄存器变量

注意:
  这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。

因为,如果定义了很多register变量,可能会超过CPU的寄存器个数,超过容量。所以只是可能

在c++中:

(1)register 关键字无法在全局中定义变量,否则会被提示为不正确的存储类。

(2)register 关键字在局部作用域中声明时,可以用 & 操作符取地址,一旦使用了取地址操作符,被定义的变量会强制存放在内存中。

在c中:

(1)register 关键字可以在全局中定义变量,当对其变量使用 & 操作符时,只是警告“有坏的存储类”。

(2)register 关键字可以在局部作用域中声明,但这样就无法对其使用 & 操作符。否则编译不通过。

	建议不要用register关键字定义全局变量,因为全局变量的生命周期是从执行程序开始,一直到程序结束才会终止,而register变量可能会存放在cpu的寄存器中,如果在程序的整个生命周期内都占用着寄存器的话,这是个相当不好的举措。

4、static

1、全局静态变量
  在全局变量前加上static,全局变量就定义成一个全局静态变量。
  存储在静态存储区,整个程序运行期间一直存在。
  初始化:未经初始化的全局静态变量会自动初始化为0。
  作用域:全局静态变量在声名它的文件之外是不可见的,准确来说从定义开始,到文件结尾。
2、局部静态变量
  在局部变量之前加上static,局部变量就成为一个局部静态变量。
  存储区域:静态存储区。
  初始化:未经初始化的全局静态变量会被初始化为0。
  作用域:作用域为局部作用域,当定义它的函数或语句块结束时,作用域结束。但当当它离开作用域时并没有销毁,仍然驻留在内存当中,只不过我们不能对它进行访问,直到该函数再次被调用。
3、静态函数
  函数的声名和定义在默认下都是extern的,但是静态函数只在声名它的文件当中可见,不能被其他文件所用,并且不会和其他cpp中的同名函数引起冲突。
注意:
  不要再头文件中声明static的全局函数,不要在cpp内声明非static的全局函数,如果你要在多个cpp中复用该函数,就把它的声明提到头文件里去,否则cpp内部声明需加上static修饰。
4、类的静态成员
  在类中,静态成员可以实现多个对象之间的数据共享,并且保证安全性。所以:静态成员是类的所有对象中的共享成员。对多个对象来说,供所有对象使用。
5、类的静态函数
  静态函数与静态成员一样,都是类的静态成员,不是对象成员,因此对静态成员的引用不需要引用。
  在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员非要引用非静态成员,可通过对象来引用。
  调用静态函数使用格式:<类名>: : <静态成员函数名>(<参数表>)

三、其他关键字

1、const

声名只读变量

//const 在前面
const int nValue; //const 修饰的是int,整型固定,但是nValue的值是也不变的
const char* pContent; //const 修饰的是char*, 指针类型固定,但是pContent是可以变的
const char* const pContent; //pContent和*pContent都被const修饰,都不可变。
 
//const 在后面
int const nValue; //const修饰的是nValue,在一定程度上和const int nValue相同,nValue的值不能修改
char const *pContent; //const修饰的是*,pContent是可以改变的
char* const pContent; //const修饰的是pContent,*pContent是可以改变的
char const * const pContent; //pContent和*pContent都被const修饰, 都不可以改
 
//const推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

2、sizeof

计算数据类型长度

注意:常用来考内存对齐与字节数

3、typedef

用以给数据类型取别名(当然还有其他作用)

typedef int size; //size是int的别名
typedef char Line[10]; //Line是具有10个char元素的数组
typedef char* pstr; //pstr是字符指针
 
typedef struct tagNode
{
    char* pItem;
    struct tagNode* pNext; //注意这里不能写下面的别称pNode替换struct tagNode*,因为此时还没定义
}*pNode;
//还可以这样做,更规范一些
struct tagNode
{
    char* pItem;
    struct tagNode* pNext;
};
typedef tagNode* pNode;

typedef和#define的区别:

//#define属于在预编译期的单纯的拷贝
typedef char* pStr;
char string[4] = "abc";
const char* p1 = string;
const pStr p2 = string;
p1++;
p2++; //错误,原因是指针的星号*是优先向右结合的,在*p1中const修饰的是char,在p2中const修饰的是char*,所以,p1可以++,但是p2不可以++

4、volatile

说明变量在程序执行中可被隐含地改变
volatile int i=10; //当要求使用volatile声明的变量的时候,读取的数就会被立即保存起来,下次使用int a=i;时不要改变i的值(如果是指针有可能会发生变化)。
//尤其是多线程中,无法判定何时这个变量会发生变化。加上volatile修饰这个变量表示这个变量是容易被修改的

一般来说,volatile用在如下的地方:
  1、中断服务程序中修改的供其他程序检测的变量需要加volatile
  2、多任务环境下各任务间共享的标志应该加volatile
  3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都有可能有不同的意义

四、C99增加的关键字(5个)

1、inline:内联函数

关键字inline必须与函数实现放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用。

2、restrict:一种类型限定符

  用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式,即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改。目的是帮助编译器进行更好的优化代码,生成更有效率的汇编代码。

3、_Bool:布尔型

4、_Complex:新增的数据类型,用来表示复数

例如:double complex x = 5.2

5、_Imaginary:虚数类型,没有实部的(目前已经和_Complex合并)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值