IOS开发教程之C语言存储方式和作用域

2020-01-12 13:49:59于丽

自动变量

被关键字auto修饰的局部变量是自动变量,但是auto关键字可以省略,因此可以得出结论:所有没有被static修饰的局部变量都是自动变量。


//
// 1.3.c
// ScopeAndLifeCycle
//
// Created by Kenshin Cui on 14-7-12.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[]) {
  int a=1;
  auto int b=2;
  printf("a=%d,b=%dn",a,b); //结果:a=1,b=2 ,a和b都是自动变量,auto可以省略
  
  //需要注意的是,上面的自动变量是存储在栈中,其实还可以存储到堆中
  char c[]="hello,world!";
  long len=strlen(c)*sizeof(char)+1;//之所以加1是因为字符串后面默认有一个空操作符不计算在长度内
  char *p=NULL;//可以直接写成:char *p;
  p=(char *)malloc(len);//分配指定的字节存放c中字符串,注意由于malloc默认返回“void *”需要转化
  memset(p,0,len);//清空指向内存中的存储内容,因为分配的内存是随机的,如果不清空可能会因为垃圾数据产生不必要的麻烦
  strcpy(p,c);
  printf("p=%sn",p);//结果:p=hello,world!
  free(p);//释放分配的空间
  p=NULL;//注意让p指向空,否则p将会是一个存储一个无用地址的野指针
  
  
  return 0;
}

当然存储自动变量的栈和堆其实是两个完全不同的空间(虽然都在运行时有效的空间内):栈一般是程序自动分配,其存储结果类似于数据结构中的栈,先进后出,程序结束时由编译器自动释放;而堆则是开发人员手动编码分配,如果不进行手动释放就只有等到程序运行完操作系统回收,其存储结构类似于链表。在上面的代码中p变量同样是一个自动变量,同样可以使用auto修饰,只是它所指向的内容放在堆上(p本身存放在栈上)。

这里说明几点:malloc分配的空间在逻辑上连续,物理上未必连续;p必须手动释放,否则直到程序运行结束它占用的内存将一直被占用;释放p的过程只是把p指向的空间释放掉,p中存放的地址并未释放,需要手动设置为NULL,否则这将是一个无用的野指针;

寄存器变量

默认情况下无论是自动变量还是静态变量它们都在内存中,不同之处就是自动变量放在一块运行时分配的特殊内存中。但是寄存器变量却是在硬件寄存器中,从物理上来说它和内存处在两个完全不同的硬件中。大家都是知道寄存器存储空间很小,但是它的效率很高,那么合理使用寄存器变量就相当重要了。什么是寄存器变量呢?使用register修饰的int或char类型的非静态局部变量是寄存器变量。没错,需要三个条件支撑:register修饰、必须是int或char类型、必须是非静态局部变量。