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.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...
随机推荐
- Apache Spark 2.3.0 正式发布
本章内容: 待整理 参考文献: Spark Release 2.3.0
- 0x01 Spring Cloud 概述
Spring Cloud Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,领导选举,分 ...
- python中的ord函数
chr().unichr()和ord() chr()函数用一个范围在range(256)内的(就是0-255)整数作参数,返回一个对应的字符.unichr()跟它一样,只不过返回的是Unicode字符 ...
- Java编程的逻辑 (82) - 理解ThreadLocal
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- 在win10企业版x64下使用curl命令
一.curl命令介绍 curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多种Linux发行版中,并且有DOS和Win32.Win64下的移植版本. 详情查看百度百科 ...
- 在linux下用命令行编译 java的eclipse项目
由于jdk的版本问题导致在windows上编译打包好的jar包放在linux服务器上运行的时候出现一点小异常,所以决定在linux上进行一次项目编译,这有两个选择1.在相同的linux环境下安装lin ...
- CentOS系统实现SSH无密码登录的方法
一.环境配置 1.服务端:CentOS release 5.3 IP:222.73.115.198 2.客服端:CentOS release 5.8 IP:192.168.4.244 二.配置SSH无 ...
- Y460 安装ubuntu 12.04系统黑屏,登录界面黑屏
ubuntu 12.04系统黑屏,登录界面黑屏,但是命令行界面可以登录,也可以正常使用,当时在装CVS,装完重启就这样了,可能是因为前一天装更新时,突然断电导致图形界面损坏,参考他人方法,终于修复,总 ...
- CentOS 7.4编译安装Nginx1.10.3+MySQL5.7.16
准备篇 一.防火墙配置 CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop firewalld.se ...
- golang net/http 包
https://studygolang.com/articles/9467 https://www.jianshu.com/p/be3d9cdc680b 客户端: 用来发送请求, 并处理返回结果. 涉 ...