C/C++学习笔记二(变量、表达式)
来源:互联网 发布:php json存储base64 编辑:程序博客网 时间:2024/05/29 18:06
变量
计算机中变量是一个标识符或者名称。
在计算机中提供给变量两个信息
1. 变量地址 ,操作系统给变量分配的若干内存的首地址
2. 变量的值 ,内存单元中存放的数据
从变量的存储位置进行区分,可分为 内存 和 CPU的寄存器 两类
从变量的生命周期进行区分,变量分为静态、动态存储两种
1. 静态存储 存储在内存的静态存储区,编译时就分配了存储空间,在运行期间有固定的存储单元,程序结束后,才会释放。
2. 动态存储 存储在动态存储区中,只有变量所在的函数被调用时,才会临时分配一段,程序调用结束后,空间便会释放。
而在C语言提供4种存储类型
1.auto 自动
2.static 静态
3.register 寄存器
4.extern 外部
外部变量和内部变量的区别 ?
外部、内部变量的区别十分简单,内部变量指的是函数内的变量,函数外的变量便是外部变量(全局变量)。
外部变量可以被其他文件所使用,他的存储方式是静态存储,它的生命周期等同于整个程序(static 对象 ,全局变量)。
而内部变量仅能被作用域内访问,他存储方式是动态存储,它生命周期在超出作用域后会被回收。(auto对象)
全局变量和静态变量的区别 ?
在C语言中,可以使用static声明一个静态变量,也可以在函数外声明一个全局变量,其他文件使用extern对该变量进行访问。他们两者的存储方式都是使用静态存储方式,存储在内存的静态存储区。
他们之前的差别在于 全局变量的作用域是整个程序。(跨文件)
而静态变量的作用域则是当前源文件,其他源文件不可访问。
说到这,即extern 不可以用来修饰 static,因为他们两者思想便是冲突的(extern 用于跨源文件,static用于限制变量在当前源文件中使用)。
他们的作用正好相反。
extern 的作用是用于多文件数据共享,
static 的作则是用于数据隔离
例如如下
//global.c#include <stdio.h>int gloablValue =2;static int staticVal = 12;void testFunc(){ printf("static value is %d",staticVal);}
//main.c#include <stdio.h>#include "global.c"extern int gloablValue;int main(){ printf("gloablValue %d \n",gloablValue); return 0;}
const 其实不是常量!
C语言中经常会使用const 修饰符,限定一个变量不允许被改变。防止意外的修改。
但是const 变量经常会被是常量,其实 const 变量是只读变量,不是常量。
下面的例子证明const 并不是常量。
运行下面代码会报错。因为指定数组大小时应该使用的是常量
const int const_array_num = 10; int arr[const_array_num] = 12;
既然const 修饰的不是常量,那const 变量能否被修改?
下面的代码访问了num的指向的内存区域,并且修改了他的值
const int num = 100; int * p = (int *)# int * p2 = p; *p = 1; printf("num = %d *p = %d *p2 = %d \n",num,*p,*p2); printf("*num = %p, p = %p , p2 = %p \n",&num,p,p2);
下面是输出的结果
num = 100 *p = 1 *p2 = 1 *num = 0x7fff5fbff728, p = 0x7fff5fbff728 , p2 = 0x7fff5fbff728
可以看到三者打印的指针是一样,但num打印的值依然是100,其实const修饰的值读取的是数据段,通过指针读取的数据保存在堆栈段。
const其实提供了一种保护机制,保证变量只能从数据段中读取数据,确保了他不被改变。
表达式
表达式是由常量、变量、函数和运算符构成的。运算符大致分为算术表达式、关系表达式、逻辑表达式、赋值表达式、条件表达式和逗号表达式等。因C语言表达式语法灵活,很有必要为提高程序可读性,在开发时遵循一些改善的建议。
ARM机器上减少使用除法与求模运算
ARM硬件上不支持除法运算,编译器调用C库的函数来实现除法运算,如需要除法运算中是程序中的瓶颈所在,可以通过减少除法运行来进行优化。
避免相似的操作符混淆
避免 = 与 == 混淆
开发时,常用到 == 与整型数据进行判断,这种情况下,如果漏写一个=会容易导致逻辑出现问题
如下例子,a=1由于写少了一个=,导致语句永远也无法走到else条件中。
int a = 123; if(a=1){ //do something }else{ }
解决的办法是将对比常量提前,若少写=时,编译器便会提前报错,这样可以在一定程度上避免误写的发生。
int a = 123; if(1==a){ //do something }else{ }
避免使用复杂的复合表达式
开发过程中应该避免使用复杂的表达式
如下方的例子,应该尽量避免
int a = 10;a+=a-1=a*=a;printf("%d\n",a);
if else 语句无论子语句多少,都应使用{}包括
形如如下的if else语句不使用{}包含时经常会让后来的代码维护者读代码时十分头疼.
if(a>0) b = 1; if(a > 100) b = 100;else b= 0;
正确做法,为每个if 、else 加上对应的{}。这样会让代码更加清晰。
if(a>0){ b = 1; if(a > 100){ b = 100; }}else{ b= 0;}
for循环中尽量将逻辑判断语句置于循环外层
如极限情况下例子会执行2*n次判断
for(int i = 0; i<n ; i++){ if(condition) { DoSomething(); }else{ DoOtherthing(); }}
以下判断语句置于外层时,极限情况下减少n-1次。当for循环次数很大时,这样的小优化是值得的。
if(condition){ for(int i = 0; i<n ; i++) { DoSomething(); }}else{ for(int i = 0; i<n ; i++) { DoOtherthing(); }}
注意typedef与#define的使用
typedef 是一种类型的新别名, 而宏是简单字符串替换
宏定义的作用时间是在 预处理阶段
typedef 的作用时间是在 编译阶段
在使用宏定义期望替换类型时,切记不可同一行类声明两个变量
typedef char * PCHAR1; #define char * PCHAR2; PCHAR1 c1,c2; PCHAR2 c3,c4;
//预处理后typedef char * PCHAR1;PCHAR1 c1,c2;char * c3,c4;
此时c1,c2的类型均是char *
此时c3 类型是 char * 而 c4的类型是char
- C/C++学习笔记二(变量、表达式)
- C语言学习笔记(二)——表达式
- c学习笔记(二)
- c 学习笔记之二 变量的存储类型
- LINUX C编程 二、常量、变量、表达式
- C#OOP之二 变量和表达式
- 【C++】学习笔记二十二——逻辑表达式
- Objective-C学习笔记(二十四)——成员变量的访问修饰符学习
- Objective-C学习笔记(二十六)——成员变量的继承学习
- c++primer学习笔记(5.0)表达式
- PHP学习笔记(二):变量、常量、表达式
- C语言学习笔记(二)--数据类型、常量和变量简介
- 《C程序设计语言》学习笔记(二)——类型、运算符与表达式
- C#.NET学习笔记7--11---算术运算符,变量赋值,变量的交换,布尔表达式1,布尔表达式2
- C语言学习笔记(二)
- 《C和指针》学习笔记(二)
- c++primer学习笔记(二)
- C++Primer学习笔记(二)
- java的初始化块
- TCP套接字编程
- WAV
- 计算机网络自顶向下 :应用层(DNS,POP)
- servlet和jsp学习(二)
- C/C++学习笔记二(变量、表达式)
- boost多个关键字索引multi_index_container
- LVS/DR模式工作原理的常见问题[转]
- hashMap的原理 深入理解
- android ReactNative混合开发之最新教程
- 封装虚拟机
- 17.7.19-聊天APP-登录界面
- spring和junit整合实例
- RAM