C和C指针小记(六)-基本声明、指针声明、typedef 、常量、作用域、链接属性、存储类型、static
1、变量的声明
声明变量的基本形式:
说明符号(一个或者多个) 声明表达式列表
说明符 (specifier) 包含一些关键字,用于描述被声明的标识符的基本类型,它也可用户改变标识符的缺省存储类型和作用域.
如:
int i;
char j, k, l;
修改变量的长度或者是否为有符号数的关键字:
//short long signed unsigned
unsigned short int a;
unsigned short a;
相等的整型说明
有符号 | 无符号 |
---|---|
short signed short | unsigned short |
short int signed short int | unsigned short int |
int signed int | unsigned int |
signed | unsigned |
long signed long | unsigned long |
long int signed long int | unsigned long int |
2、指针的声明
几个需要注意的点
//正常的声明一个指向整型指针
int *a;
//也可以这样写, *与int 类型标识符贴近.
int* a;
//需要注意的是 只有b 是整型指针, c,d是整型
int *b, c, d;
//只有*紧贴变量名时才使得 b,c,d 都是指向整型的指针
int *b, *c, *d;
//声明+初始化一个字符串
char *message = "hello world!";
//上句相当于这两行代码
char *message;
message = "hello world!";
3、typedef
typedef 允许程序员为各种数据类型定义新的名字
例如:
//声明一个指向字符的指针prt_to_char
char *prt_to_char;
//用typedef 把 prt_to_char作为指向字符的指针类型的新名字.
typedef char *ptr_to_char;
//可以使用这个新名字定义 指向字符的指针
ptr_to_char a;
注意:应该使用typedef 而不是 #define 来创建新的类型名 ,因为后者无法处理指针类型
定义复杂的类型名字时应该使用typedef 如:函数指针或者指向数组的指针
4、常量
ANISI C允许声明常量.
常量的样子和变量完全一样,只是不能被修改.声明时使用const关键字.
如
//常量的声明,但是无法被更改
int const a;
const int a;
//所以常量声明和定义是一起的
int cosnt a = 1;
//当涉及指针变量时,需要注意
//pi 是一个普通的指向整型的指针,
int *pi;
//pic 是一个指向整型常量的指针.你可以修改指针的值,但你不能修改它所指向的值.
int const *pic;
//pcc 为指向整型的常量指针.此时指针是常量,它的值无法被修改,但你可以修改它所指向的整型的值.
int * const pcc;
//cc无论是指针还是它所指向的值都是常量,不允许修改
int const * const * cc;
*cosnt 的结合是从右往左的,如 int const pcc; const修饰,指针是不能被修改的.又如 int const pic ,指针所指的值是不能被修改的
#define 也是可以定义常量的, 用字面值的地方都可以用 #define 来定义
5、作用域 scope
变量在程序的某个部分被声明的时候,它只有在程序的一定区域才能被访问. 这个区域由标识符作用域决定.
编译器可以确认4中不同类型的作用域:
文件作用域、函数作用域、代码块作用域、原型作用域
6、链接属性
链接属性一共有3种:external(外部)、internal(内部)、none(无)
没有链接属性的标识符(none )总是被当作单个个体,也就是该标识符的多个声明被当作独立不同的实体.
属于internal链接属性的标识符在同一个源文件的所有声明中都指向同一个实体,但位于不同源文件的多个声明则分属不同的实体.
属于 external 链接属性的标识符不论声明多少次,位于几个源文件都标示同一个实体.
关键字 extern 和 static 用于在声明中修改标识符的链接属性.如果某个声明在正常情况下具有 extrenal 链接属性,在它前面加上 static 关键字可以使它的链接属性变为 internal.
如
// b 的作用域变为该源文件所私有
static int b;
//函数 foo的作用域为它所在的源文件所私有, 可以防止它被其他源文件调用
static int foo(int d);
7、存储类型
变量的存储类型是指存储变量值的内存类型.
存储类型决定来变量何时创建、何时销毁、以及它的值保持多久.
变量存储的三个地方:普通内存、运行时堆栈、硬件寄存器.
变量的缺省存储类型取决于它的声明位置.
凡是在任何代码块之外声明的变量,总是存储与静态内存中,也就是不属于堆栈的内存,这类变量称为静态(static)变量.对于这类变量,你无法为他们指定其他存储类型. 静态类型在程序运行之前创建,在程序的整个执行期间始终存在.它始终保持原先的值,除非给它赋一个不同的值或者程序结束.
在代码块内部声明的变量的缺省存储类型都是自动(automatic), 也就是说它存储于堆栈中,称为自动(auto)变量.一个函数被多次调用,它内部的自动变量会被多次创建和销毁.对于在代码块内部声明的变量,如果给它加上static关键字,可以使它的存储类型从自动变为静态.具有静态存储类型的变量在整个程序执行过程中一致直存在,而不仅仅在声明它的代码块的执行时存在.
注意:修改变量的存储类型,并不代表修改变量的作用域,它仍然只能在该代码内部按名字访问.函数的形式参数不能声明为静态,因为实参总是在堆栈中传递参数,用于支持递归
关键字register可用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量.通常,寄存器变量比存储于内存的变量访问起来效率更高.但是编译器并不一定要理睬 register关键字,如果有太多的变量被声明为 register, 它只选取前几个实际存储于寄存器中,其余的就按照普通自动变量处理.
8、static 关键字
特别提醒: 不同的上下文环境,static关键字具有不同的作用
-当它用与函数定义时,或用于代码块之外的变量声明时,static 关键字用于修改标识符的链接属性, 从 external 改为 internal, 但标识符的存储类型和作用域不受影响.用这种方式声明的函数或变量只能在声明他们的源文件内部访问.
-当它用于代码块内部的变量时, static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响.用这种方式声明的变量在程序执行之前创建,并在程序的整个执行期间一致存在,而不是每次在代码块开始执行是创建,在代码块执行完毕后销毁.
9、作用域、链接属性、存储类型总结
变量类型 | 声明的位置 | 是否存于堆栈 | 作用域 | 如果声明为static |
---|---|---|---|---|
全局 | 所有代码块之外 | 否 | 从声明处到文件尾 | 不允许从其他源文件访问 |
局部 | 代码块起始处 | 是 | 整个代码块 | 变量不存储于堆栈中,它的值在真个执行期一直保持 |
形式参数 | 函数头部 | 是 | 整个函数 | 不允许 |
C和C指针小记(六)-基本声明、指针声明、typedef 、常量、作用域、链接属性、存储类型、static的更多相关文章
- C和指针笔记 3.6链接属性
链接属性决定如何处理在不同文件中出现的标识符.标识符的作用域也它的链接属性有关,但这两个属性并不相同. 没有链接属性的标识符(none)总是被当作单独的个体,也就是说该标识符的多个声明被当作独立不同的 ...
- C和C指针小记(十六)-动态内存分配
动态内存分配 1.1 为什么使用动态内存分配 直接声明数组的方式的缺点: 1) 声明数组必须指定长度限制.无法处理超过声明长度的数组. 2) 如果声明更大的常量来弥补第一个缺点,会造成更多的内存浪费. ...
- C和指针 第六章 数组名与指针
指针的算术运算符是指针和数组之间的一种关联,但不是唯一关联: 可以使用数组名作为指向数组第一个元素的指针,但是不可以给数组名赋新的值. //如下声明a int a[10]; //用a作为指向数组第一个 ...
- C语言指针与数组的定义与声明易错分析
部分摘自<C语言深度解剖> 1.定义为数组,声明为指针 在文件1中定义: char a[100]; 在文件2中声明: extern char *a; //这样是错误的 这里的extern告 ...
- C和C指针小记(十八)-使用结构和指针-双向链表
1.双链表 1.1 双向链表的声明 在一个双链表中,每个节点都包含两个指针--指向前一个节点的指针和指向后一个节点的指针. 声明 typedef struct NODE { struct NODE * ...
- C和C指针小记(十七)-使用结构和指针-链表
1.链表 链表(linked list)即使是一些包含数据的独立数据结构的(Node)集合. 链表中的每个节点通过链或指针链接在一起. 程序通过指针访问链表中的节点. 节点通常是动态分配的,但也有由节 ...
- C和C指针小记(十五)-结构和联合
1.结构 1.1 结构声明 在声明结构时,必须列出它包含的所有成员.这个列表包括每个成员的类型和名称. struct tag {member-list} variable-list; 例如 //A s ...
- C和C指针小记(十三)-数组
1.1 一维数组 一维数组的声明: int a[10]; 这里a就是一个数组. 数组a的类型就是一个指向整型的常量指针. 但是数组和指针是**不相同**的. **数组具有特定数量的元素,而指针只是一个 ...
- Android JNI编程(六)——C语言函数指针、Unition联合体、枚举、Typedef别名、结构体、结构体指针
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:函数指针 1.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...
随机推荐
- 11g新特性 -- Virtual Private Catalogs
在oracle 11g之前版本中,如果用户只是需要访问recovery catalog 中的某个数据库,但是我们却只能将整个recovery catalog授权给他,无法做到严格限制. 现在,virt ...
- python下申明式的对象关系DB映射器--Pony
之前看到了Sails.js的waterline提供了声明式的关系型对象与DB的映射器,惊为天人,可以说是极大地提升了效率. 利用waterline的对象关系模型,用户可以直接使用javascript语 ...
- Sql Server 阻塞的常见原因和解决办法
1. 由于语句运行时间太长而导致的阻塞,语句本身在正常运行中,只须等待某些系统资源 解决办法: a. 语句本身有没有可优化的空间 b. Sql Server 整体性能如何,是不是有资源瓶颈影响了语句执 ...
- Json字符串转DataTable
/// <summary> /// 将json转换为DataTable /// </summary> /// <param name="strJson" ...
- GNU Binutils简介及基本用法
[时间:2017-06] [状态:Open] [关键词:GNU, binutils, as, ld, ar, 基础工具,linux,链接器,汇编器] 0 简介 GNU Binary Utilities ...
- CodeCombat编程游戏
一. 介绍 官方网站:http://cn.codecombat.com/ 项目地址:https://github.com/codecombat/codecombat CodeCombat 是一个通过玩 ...
- 【iCore1S 双核心板_ARM】例程十五:USB_HID实验——双向数据传输
实验方法: 1.USB_HID协议免驱动,此例程不需要驱. 2.将跳线冒跳至USB_OTG,通过Micro USB 线将iCore1S USB-OTG接口与电脑相连. 3.打开上位机软件usb_hid ...
- FPGA编程—组合逻辑编码器等verilog实现
本篇博客主要实现对组合逻辑电路的一些常用模块的实现.组合逻辑中,包括译码器,编码器,输入输出选择器,数值比较器,算法单元等. 先来实现编码器,最常用的8-3编码器,这里先讲一下要用到的case ,c ...
- git合并分支上指定的commit
merge 能够胜任平常大部分的合并需求.但也会遇到某些特殊的情况,例如正在开发一个新的功能,线上说有一个紧急的bug要修复.bug修好了但并不像把仍在开发的新功能代码也提交到线上去.这时候也许想要一 ...
- SQL Server2008 删除登录记录
SQL Server Management Studio登陆窗口 清空这些多余的登陆名 主要是删除SqlStudio.bin文件 WinXP: C:\Documents and Set ...