C第八天

第八课  作用域与可见性
一、变量和作用域
1.局部变量:定义在函数或语句块(被一对{}括起来的若干条语句)中的变量(包括形参)。局部变量的可见性仅局限在定义该变量的函数或语句块中。其生命期由函数栈的压入和弹出决定。内层作用域的标识符会隐藏外层作用域的同名标识符。
2.全局变量:定义在所有函数之外的变量。其生命期与进程一致。在程序中居于最外层作用域。全局变量全局可见。
练习:实现迷你银行。显示如下菜单:
[1] 清户 // 余额清零
[2] 存款 // 余额+存入
[3] 取款 // 余额-取出
[4] 查询 // 打印余额
[5] 结息 // 余额*(1+利率)
[6] 调息 // 修改利率
[0] 退出 // 结束程序
每个菜单项用一个独立的函数处理,账户余额和利率用全局变量保存。
全局变量的外部声明:在一个源文件(b.c)中访问定义在另一个源文件(a.c)中的全局变量,需要在访问之前,对其进行外部声明。
// a.c
int g = 100; // 定义于a.c
// b.c
extern int g; // 外部声明于b.c
void foo (void) {
  g++;
}
全局变量的外部声明一定要和改变量被定义的类型相一致。
3.静态局部变量:作用域和生命期与全局变量一致,但可见性与局部变量一致。
4.静态全局变量:将全局变量的可见性限制在定义该变量的源文件中。
5.全局函数:即通常所言函数。在C语言所有的函数都是全局函数。
6.静态全局函数:只有在定义该函数的源文件中才能调用该函数。
             作用域和生命期  可见性
    局部变量 函数/块         函数/块
静态局部变量 进程            函数/块
    全局变量 进程            所有文件
静态全局变量 进程            定义文件
    全局函数 进程            所有文件
静态全局函数 进程            定义文件
练习:实现堆栈模块(静态库),构建应用,使用该模块中的堆栈函数,完成按任意进制打印整数的任务。
push压入,pop弹出,top获取栈顶。
push (10); // 10
push (20); // 10 20
push (30); // 10 20 30
top (); // 返回30
pop (); // 10 20
pop (); // 10
push (40); // 10 40
后进先出
在堆栈模块中实现如下函数:
int capacity (void); // 获取容量
int size (void); // 获取数据个数
bool full (void); // 判满
bool empty (void); // 判空
bool push (int data); // 压入,成功返回true,失败返回false
bool pop (void); // 弹出,成功返回true,失败返回false
void clear (void); // 清空
int top (void); // 获取栈顶
#include <stdbool.h>
bool:布尔类型(int)
true:真(1)
false:假(0)
提示:用全局数组存放数据,用一个全局变量标识栈顶的位置。
1234=1*10^3+2*10^2+3*10^1+4*10^0
%10 -> 4
/=10 -> 1*10^2+2*10^1+3*10^0
%10 -> 3
/=10 -> 1*10^1+2*10^0
%10 -> 2
/=10 -> 1*10^0
%10 -> 1
第九课  指针与字符串
一、指针
1.指针就是存放地址的变量。在32位系统上,一个指针变量占用4个字节。在64位系统上,一个指针变量占用8个字节。
2.指针类型、取地址、解引用
1)指针类型
int* pa;
int *pa;
int * pa;
语义:pa是一个指针,该指针指向一个int型的数据,即pa存放一个int型数据的地址。
int* pa, pb; // pa是int*,pb是int
int *pa, *pb;
2)取地址——&
int a;
int* pa = &a; // pa指向a,a是pa的目标,pa是a的指针,pa中存放着a的地址。
3)解引用(取目标)——*
*pa = 100; // 将100赋值给pa的目标,即赋值给a
3.指针的用法
1)将指针作为函数的参数,传递变量的地址,进而在多个函数中访问相同的内存数据。

2)指针也可以作为函数的返回值,但是不要返回指向局部变量的指针。因为函数返回以后,其局部变量所占用的内存将随函数栈一起被释放,所得到的指针为野指针。

#include <stdio.h>
double g_balance = 0.0;
double g_rate = 0.01;
void clean (void) {
  scanf ("%*[^\n]");
  scanf ("%*c");
}
int menu (void) {
  printf ("--------\n");
  printf ("迷你银行\n");
  printf ("--------\n");
  printf ("[1] 清户\n");
  printf ("[2] 存款\n");
  printf ("[3] 取款\n");
  printf ("[4] 查询\n");
  printf ("[5] 结息\n");
  printf ("[6] 调息\n");
  printf ("[0] 退出\n");
  printf ("--------\n");
  printf ("请选择:");
  int sel = -1;
  scanf ("%d", &sel);
  clean ();
  return sel;
}
void query (void) {
  printf ("当前余额:%.2lf\n", g_balance);
}
void clear (void) {
  g_balance = 0;
  query ();
}
void save (void) {
  printf ("存款金额:");
  double save;
  scanf ("%lf", &save);
  clean ();
  g_balance += save;
  query ();  
}
void withdraw (void) {
  printf ("取款金额:");
  double withdraw;
  scanf ("%lf", &withdraw);
  clean ();
  if (g_balance < withdraw)
    printf ("余额不足!\n");
  else {
    g_balance -= withdraw;
    query ();
  }
}
void settle (void) {
  g_balance *= (1 + g_rate);
  query ();
}
void adjust (void) {
  printf ("当前利率:%.2lf\n", g_rate);
  printf ("存款利率:");
  scanf ("%lf", &g_rate);
  clean ();
}
int main (void) {
  for (;;)
    switch (menu ()) {
      case 1:
        clear ();
        break;
      case 2:
        save ();
        break;
      case 3:
        withdraw ();
        break;
      case 4:
        query ();
        break;
      case 5:
        settle ();
        break;
      case 6:
        adjust ();
        break;
      case 0:
        printf ("再见!\n");
        return 0;
      default:
        printf ("选择错误!\n");
        break;
    }
  return 0;
}

#include <stdio.h>
int g = 10;
void foo (void) {
  g++;
}
void bar (int a) {
  g += a;
}
int main (void) {
  g = 100;
  foo ();
  bar (g);
  printf ("g=%d\n", g); // 202
  return 0;
}
  #include <stdio.h>
int add (int a, int b) {
  int c = a + b;
  return c;
}
int main (void) {
  int a = 100, b = 200;
  {
    int a = 300, b = 400;
    //int add = a + b;
    printf ("%d\n", add (a, b));
    // 700
  }
  printf ("%d\n", add (a, b));
  // 300
  // 700
  return 0;
}

#include <stdio.h>
void swap (int a, int b) {
  int c = a;
  a = b;
  b = c;
}
void swap2 (int* a, int* b) {
  int c = *a;
  *a = *b;
  *b = c;
}
int main (void) {
  int a = 100;
  printf ("a=%d\n", a);
  printf ("&a=%p\n", &a);
  int* pa = &a;
  printf ("pa=%p\n", pa);
  printf ("*pa=%d\n", *pa);
  printf ("sizeof(pa)=%d\n", sizeof (pa));
  int b = 200;
  swap (a, b);
  printf ("%d,%d\n", a, b); // 100,200
  swap2 (&a, &b);
  printf ("%d,%d\n", a, b); // 200,100
  return 0;
}

#include <stdio.h>
int* foo (void) {
  int a = 100;
  return &a;
}
int* bar (void) {
  double b = 200;
  return &b;
}
int hum (void) {
  int c = 300;
  return c;
}
int main (void) {
  int* p = foo ();
  bar ();
  printf ("%d\n", *p);
  printf ("%d\n", hum ());
  return 0;
}

#include <stdio.h>
// 输入数据
void input (float scores[], int sts) {
  int i;
  for (i = 0; i < sts; i++) {
    printf ("第%d个学生:", i+1);
    scanf ("%f", &scores[i]);
  }
}
float g_max;
// 计算总分同时求最高分
float total_max (float scores[], int sts) {
  float total = 0;
  int i, max = 0;
  for (i = 0; i < sts; i++) {
    total += scores[i];
    if (i != max && scores[i] > scores[max])
      max = i;
  }
  g_max = scores[max];
  return total;
}
int main (void) {
  printf ("学生人数:");
  int sts;
  scanf ("%d", &sts);
  float scores[sts];
  input (scores, sts);
  float t = total_max (scores, sts);
  printf ("总分:%g,平均分:%g,最高分:%g\n", t, t / sts, g_max);
  return 0;
}

#include <stdio.h>
// 输入数据
void input (float scores[], int sts) {
  int i;
  for (i = 0; i < sts; i++) {
    printf ("第%d个学生:", i+1);
    scanf ("%f", &scores[i]);
  }
}
// 计算总分同时求最高分
float total_max (float scores[], int sts, float* pmax) {
  float total = 0;
  int i, max = 0;
  for (i = 0; i < sts; i++) {
    total += scores[i];
    if (i != max && scores[i] > scores[max])
      max = i;
  }
  *pmax = scores[max];
  return total;
}
int main (void) {
  printf ("学生人数:");
  int sts;
  scanf ("%d", &sts);
  float scores[sts];
  input (scores, sts);
  float max;
  float t = total_max (scores, sts, &max);
  printf ("总分:%g,平均分:%g,最高分:%g\n", t, t / sts, max);
  return 0;
}

#include <stdio.h>
#include "data.h"
void show (void) {
  g_data = 0;
  printf ("%d,%lf\n", g_value, g_data); // 200,0
}
int main (void) {
  show ();
  foo ();
  //printf ("g_static=%d\n", g_static);
  add ();
  return 0;
}

#include <stdio.h>
void foo (void) {
  static int i = 0; // 静态局部
  printf ("%d\n", ++i);
}
void bar (void) {
  //printf ("%d\n", i);
}
int main (void) {
  int i;
  for (i = 0; i < 10; i++)
    foo ();
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值