C语言自学笔记
嗯,几年前学的,当时看的是郝斌09年的c语言视频,虽然他是用notepad写的,但是他讲的很详细,学起来很容易。那时候,我好像学C++刚结束????????,为了看C++和C的不同,以及准备考二级C,所以才去看的。当时用Word写了70多页笔记,现在想想,做笔记是耗费了我不少时间,不过还是学会了不少,尤其指针那里,我当时把什么字符、字符串、字符数组、字符指针一起比较,还把指针、指针函数,函数指针一起比较????????。好了不说了,让我来贴笔记吧。(格式下次调,我这用手机写的,不好调)
VC++6.0 软件测试
1 数据类型
整数
整型 - - int - -4
短整型 - - short (int) - -2
长整型 - - long (int) - -4
双长整型 – long long - -8
浮点数
单精度浮点数 - - float - - 4
双精度浮点数 - - double - - 8
字符
char - - 1
字符用单引号表示 ,字符串用双引号表示
例如:
‘A’ ‘b’ “A” ( A \0 ) “ABC”
2 什么是字节
字节就是存储数据的单位,并且是硬件所能访问的最小单位
默认进制为十进制
0(零)+数 为八进制
0X(零 字母X)为十六进制4
3 什么是ASCII
ASCII不是一个值,而是一种规定,规定了不同字符是使用哪个整数值去表示,它规定了
‘A’–65
‘B’–66
‘a’–97
‘b’–98
‘O’–48
字符的存储[字符本质上与整数的存储方式相同]
4 基本的输入和输出函数的用法
printf()—输出 :将变量的内容输出到显示器上
四种用法
printf(“<式样化字符串>”, <参量表>);
式样化字符串包括两部分内容:一部分是正常的字符(非控制输出符),这些字符将按原样输出,另一部分是式样化规定字符(控制输出符),以%开端,后跟一个或多个规定字符,用来确定输出的样式。
式样化字符串的样式
%[标志][输出最小宽度][精度][长度]式样字符
标志: 意义
: 结果左对齐,右边填空格
- : 输出标记(正号或负号)
空格:输出值为正时输出空格,为负时输出负号
1、 prinf(“字符串”);
2、 printf(“输出控制符”,输出参数);
3、 printf(“输出控制符1 输出控制符2…”,输出参数1, 输出参数2);
输出的控制符和输出参数的个数必须一一对应
4、 printf(“输出控制符 非输出控制符”, 输出参数);
输出控制符(有%的)包含如下:
%d - - int 以十进制输出
%ld - - long int
%c - - char
%f - - float
%lf - - double
%x (或者%X 后者 %#X) - - int 或 long int 或 short int 十六进制
%o - - 同上
%s - - 字符串
非输入控制符按原样输出
为什么需要输出控制符
01 组成的代码可以表示数据也可以表示指令
如果01组成的代码表示的是数据,那么同样的 01代码的组合以不同的输出格式输出
就会有不同的输出结果
例子1:
#include<stdio.h>
int main(void)
{
prinft(“哈哈!\n”); //\n表示换行
int i = 10;
printf("%d\n", i); //d是十进制
int j = 3;
int k = 5;
printf("%d %d\n", j, k); //OK 3 5
printf("%d%d\n", j, k); // 35
printf("%d\n", j, k); //error 输出控制符和输出参数的个数不匹配
printf(“i = %d j = %d\n”, j, k); // i = 3 j = 5
return 0;
}
测试%x %X %#x %#X 的用法
例子2
#include <stdio.h>
int main (void)
{
int x = 47; //47 是十进制
printf("%x\n", x); // 输出结果:2f
printf("%X\n", x); // 输出结果:2F
printf("%#x\n", x); // 输出结果:0x2f
printf("%#X\n", x); // 输出结果:0X2F %#X 推荐使用
return 0;
}
5 scanf()的使用方法
【通过键盘将数据输入到变量中】
两种用法:
用法一:scanf (“输入控制符”, 输入参数);
功能: 将从键盘中输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中
用法二: scanf(“非输入控制符 输入控制符”, 输入参数);
功能: 将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以
输入参数的值为地址的变量中 。非输入控制符必须原样输入
如何使用scanf 编写出高质量代码
使用 scanf 之前最好先使用printf提示用户以什么样的方式来输入
scanf 中尽量不要使用非输入控制符,尤其是不要用\n
应该编写代码对用户的非法输入做适当的处理【非重点】
while ((ch=getchar())!=’\n’)
continue
例子1:
# include < stdio.h>
int main (void)
{
int i;
// i = 10;
scanf (“%d”, &i); //&i 表示的i的地址 &是一个取地址符
printf (“i = %d\n”, i); //i = 10
return 0;
}
123
i = 123
例子2:
#include <stdio.h>
int main (void)
{
int i;
scanf (“m%d”,&i);//m123是正确的输入,123是错误的输入
printf (“i = %d\n”, i);
return 0;
}
m123 m123n
i = 123 i = 123
例子3:
#include <stdio.h>
int main (void)
{
int i,j,k;
scanf (“%d %d”, &i, &j); // scanf (“%d,%d,%d”, &i, &j, &k);
printf (“i = %d, j =%d\n”, i, j);// printf (“i = %d, j =%d, k=%d\n”, i, j,k);
return 0;
}
1 2 1 2 3 1, 2, 3
i = 1 j = 2 i = 1, j = -858993460, k = - 858993460 i = 1, j = 2, k = 3
例子4
scanf 对用户非法输入的处理
include <stdio.h>
int main (void)
{
int i;
scanf(“%d”, &i);
printf(“i =%d\n”, i);
//…
while ((ch=getchar())!=’\n’)
continue
int j;
scanf (“%d”, &j);
printf(“j =%d\n”, j);
return 0;
}
123m //读m 的时候自动报错 123m
i = 123 i =123
j = -858993460 89
j = 89
include <stdio.h>
int main (void)
{
int i;
char ch;
scanf(“%d”, &i);
printf(“i =%d\n”, i);
scanf(“%c”, &ch);
printf(“ch =%c\n”, ch);
return 0;
}
12m 12nm
i = 12 i = 12
ch = m ch = n(因为char 占一个字节)
6 运算符
算术运算符
+ - * /(除) 取整 %(取余数)
除法/的运算结果和运算对象的数据类型有关,两个数都是int,则商就是int,若商有小数,则截取小数部分;被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不截取小数部分。
16/5 = =3 16/5.0 = =3.20000 -13/4 = =-4 -13/-3 = =4 3/5 = =0
取余%的运算符对象必须是整数,结果是整除后的余数,其余数的符号与被除数(%左边的数)相同
13%3 = =1 13%-3 = =1 -13%3 = =-1
-13%23 = =-13 -13%-23 = =-13 3%5 = =3
规律:%中,若左边的数小于右边的数,则结果就为左边的数;若左边的数等于右边的数,则结果就为0;右边是1,结果为0
字符串数据和任何数据使用+都是相连接,最终都会变成字符串。
关系运算符
> >= < <= !=(不等于) = =(等于)
逻辑运算符
!(非) &&(并且) ||(或)
!真 假
!假 真
真&&真 真
真&&假 假
假&&真 假
假&&假 假
真||假 真
假||真 真
真||真 真
假||假 假
C语言对真假的处理
非零即真 零是假
真是1表示 ,假是0表示
&&左边的表达式为假,右边的表达式肯定不会执行 (不含有分号的是表达式, 含有分号的是语句)
||左边的表达式为真,右边的表达式肯定不会执行
赋值运算符
= += *= /= -=
优先级别:算数 > 关系 > 逻辑 > 赋值
三目运算符: ?:
使用方法:表达式?值1:值2
结果:表达式为真,则结果为值1,否则值为值2
7 流程控制语句
【是我们学习C语言的第一个重点】
什么是流程控制
程序代码执行的顺序
流程控制的分类 : 顺序和选择
定义:某些代码可能执行,也可能不执行,有选择性的执行某些代码
分类:
7.1 IF最简单的用法
if (表达式)
语句
功能:如果表达式为真,执行语句;如果表达式为假,语句不执行
include <stdio.h>
int main (void)
{
if (3 > 2)
printf(“AAAA\n”);
return 0;
}
if的范围问题
1、
if (表达式)
语句A
语句B
解释:if默认只能控制语句A的执行或不执行;if语句无法控制语句B的执行或不执行;
或者讲:语句B一定会执行,语句A可能执行也可能不执行
2、
if (表达式)
{
语句A;
语句B;
}
此时if语句可以控制语句A和语句B
由此可见: if默认只能控制一个语句执行或不执行,如
果想控制多个语句的执行或不执行,就必须把这些语句用{}括起来
if…else…的用法
1、if(表达式)
语句1;
else
语句2;
若表达式成立,则执行语句1;否则执行语句2,(只要有一个满足,整条if …else …语句就结束)
2、 if (表达式)
{
语句1;
语句2;
}
else
{
语句3;
语句4;
}
表达式成立 语句1和语句2均执行,若表达式不成立,则语句3 和语句4均执行
注意:else 不能单独存在,必须与if组合,且else与它上方最近的if 相组合
if …else if…else…的用法
if (表达式1) ①
A;
else if (表达式2) ②
B;
else if (表达式3) ③
C;
else ④
D;
①成立,则执行A;①不成立②成立,则执行B;
①②均不成立③成立,则执行C;①②③均不成立④成立则执行D
(只要有一个满足,整条if …else …语句就结束)
include <stdio.h>
int main (void)
{
double delta = 3;
if (delta > 0)
printf(“有两个解!\n”);
/{
printf(“有两个解!\n”);
printf(“哈哈\n”);
}/
else if (delta == 0)
printf(“有一个唯一解\n”);
else
printf(“无解\n”);
return 0;
}
有两个解 有两个解
哈哈
C语言对真假的处理
非零即真,零就是假
真用1表示,假用0表示
if举例- -求分数的等级
例子1:
include <stdio.h>
int main (void)
{
float score ;
printf(“请输入您的成绩\n”);
scanf(“%f”,&score);
if (score > 100)
printf (“这是做梦\n”);
else if (score>=90 && score<=100)
printf(“优秀\n”);
else if (score>=80 && score<90)
printf(“良好\n”);
else if (score>=60 && score<80)
printf(“及格”):
else if (score>=0 && score<60)
printf(“不及格”);
else
printf(“输入的分数不合理”);
return 0;
}
例子2:
include <stdio.h>
int main (void)
{
int a, b, c;
int t;
printf(“请输入三个整数(中间以空格分隔)\n”);
scanf(“%d %d %d”, &a, &b, &c);
//编写代码完成a是中最大值,b是中间值, c 是最小值
if (a < b)
{
t = a;
a = b;
b = t;
}
if (a < c)
{
t = a;
a = c;
c = t;
}
if (b < c)
{
t = b;
b = c;
c = t;
}
return 0;
}
if的常见问题解析
1、空语句的问题
if(3 > 2);
等价于
if (3 > 2)
; //这是一个空语句
2、 if (表达式1)
A;
else
B ;
是正确的
if (表达式1);
A;
else
B ;
是错误的
3、
if (表达式1)
A;
else if (表达式2)
B;
else if (表达式3)
C;
else
D; 去掉后,语法不会出错,但逻辑上有漏洞
即使表达式1和2都成立,也只会执行A语句
4、
if (表达式1)
A;
else if (表达式2)
B;
else if (表达式3)
C;
else (表达式4); //7行
D; 加上分号后,语法不会出错,
但逻辑上是错误的
else (表达式4) 比较 else (表达式4);
D; D;
这样写是不对的,正确的写法是:
要么去掉7行的(表达式4)
要么在7行else后面加if
7.2 switch 循环语句
(注意下方的常量表达式)
switch (表达式)
{
case 常量表达式1: 语句 1; //break;
case 常量表达式2: 语句2; //break;
. . . .
. . . .
. . . .
case 常量表达式n : 语句 n; //break;
default : 语句n+1;
}
没有break 语句使程序跳出swicth 语句 则程序将从选中的相应的语句开始,一直执行到右大括号处,若有break 语句,则每执行一条语句,都会跳出该循环
If语句可以判断一个区间,执行效率比较低;switch 语句执行效率比较快,不可以进行区间判断;三目运算符 结构清晰不适于嵌套
7.3 for循环语句
定义: 某些代码会被重复执行
分类
格式:
for (语句1; 条件语句;循环变量 )
语句A;
条件成立
语句1 一> 条件语句 -------> 语句A —> 循环变量–>条件语句
跳出循环
执行的流程【重点】
单个for 循环的使用
for (1; 2; 3)
语句A;
多个for 循环的使用
1、
for (1; 2; 3) //1
for (4; 5; 6) //2
A; //3
B; //4
整体是两个语句,1 2 3是第一个语句 4 是第二个语句
2、
for (1; 2; 3)
for (4; 5; 6)
{
A;
B;
}
加大括号后整体是一个语句
for (7; 8; 9)
for (1; 2; 3)
{
A;
B;
for (4; 5; 6)
C;
}
加大括号后整体是一个语句
例子: 1 + 2 + 3 + …+ 100
#include <stdio.h>
int main (void);
{
int i;
int sum;
for(i=1; i<=100; ++i)
sum = sum + i;
printf(“sum = %d\n”, sum);
return 0;
}
强制类型转化
格式:
(数据类型) (表达式)
功能:
把表达式的值强制转化为前面所执行的数据类型
例子: (int)(4.5 + 2.2) 最终值是6
(float)(5) 最终值是 5.000000
浮点数的存储所带来的问题
float 和 double 都不能保证可以精确的存储一个小数
举例:
有一个浮点型变量 x(存储浮点数的近似值) ,如何判断 x 的值是否为零
if (|x -0.000001| < 0.000001)
是零
else
不是零
循环变量不能定义成浮点型
死循环是指:程序在执行循环时,没有循环出口(永真)
7.4 while 循环语句
while (表达式)
{
语句A;
循环体;
}
1、 只要表达式成立,语句就执行,否则跳出循环
2、与for 的相互比较
for (1; 2; 3) while (2)
A; 等价于 {
A;
3;
}
7.5 do …while 循环语句
do
{
循环体语句;
}while (表达式); 注意:此处有分号
1、 一般情况下,用 while 语句和 do …while 语句处理同一问题时,若两者的循环体部分是一样的,他们的结果也是一样的。 但是如果
while 后面的表达式一开始就为假(0值),则两种循环的结果是不相同的。
2、do …while 语句中while 后面的分号 ;是必不可少的
8 break 和 continue
8.1 break语句的格式:
break;
break语句只能用在循环语句和switch语句(开关语句)中,
break语句在switch语句中的用法同上,在循环语句体中使用并被执行时,可以使程序终止循环
break出现在循环中,作用是跳出当前内循环语句,执行后面的代码。
break 语句对 if 语句不起作用
在多重循环中 一个break 语句只能向外跳出一层。
8.2 continue语句的格式
continue;
continue语句只能作用在循环语句的循环体中,作用是结束本次循环,即跳过循环体中剩余的语句,转到判断循环条件的位置,直接判断循环条件,决定是否重新开始下一次循环。直接结束本次循环,不影响下一次循环。
continue 语句通常与if 语句一起使用,即满足某一条件时便终止该次循环。
9 数组
9.1 一维数组
怎样定义一维数组
为n个变量连续分配存储空间
所有的变量数据类型必须相同
所有变量所占的字节大小必须相等
声明: 数据类型 数组名 [数据个数];
int a[5];
0 1 2 3 4
数组下标都是从0开始
数组下标和第几个中的几相差一,下标比几小一
有关一维数组的操作
初始化
声明的同时初始化(完全初始化)
int a [5] = {1, 2, 3, 4,5}
(不完全初始化)未被初始化的元素自动为0
int a [5] = {1, 2, 3};
不初始化,所有元素都是垃圾值(随机值)
声明后赋值
int a [4];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
只有在定义的同时才可以整体赋值,其他情况下整体赋值都是错误的
int a[5];
清零
int a[5] = {0}
几种常见的错误的写法:
int a[5];
a[5] = {1, 2, 3, 4, 5};
只有在定义数组的同时才可以整体赋值,
其他情况下整体赋值都是错误的
int a[5] = {1, 2, 3, 4, 5};
a[5] = 100 // error 因为没有a[5]这个元素,最大的为a[4]
int a[5] = {1, 2, 3, 4, 5};
int b[5];
如果要把a数组中的值全部复制给b数组,错误的写法
b = a;//error
数组名不代表数组中所有元素。
数组名即为数组中第一个元素的地址,即为首地址
正确的写法
for(int i=0; i<5; i++)
b[i] = a[i];
例子:
#include <studio.h>
Int main(void)
{
int a[5];
return 0;
}
数据倒置
include <studio.h>
int main(void)
{
int a[7] = {1, 2, 3, 4, 5, 6, 7};
int i,j, t;
i = 0;
j = 6;
while(i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
i++;
}
for(i=0; i<7; i++)
printf(“%d\n”, a[i]);
return 0;
}
9.2 二维数组
构成一个平面
声明: 数据类型 数组名 [数据个数1] [数据个数2];
行数 列数
int a[3][4];
总共是12个元素,可以当做3行4列看待,这12个元素的名字依次是:
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
a[i][j] 表示第i+1行第j+1列的元素
int a[m][n]; 该二维数组右下角位置的元素只能是 a[m-1][n-1]
声明的同时初始化
int a[2][3] = {1,2,3,4,5,6};
int a[2][3] = {{1 , 2, 3}, {4, 5 ,6}};
声明后再赋值:
int a[2][3];
int a[0][0] = 1;
int a[0][1] = 2;
int a[0][2] = 3;
int a[1][0] = 4;
int a[1][1] = 5;
int a[1][2] = 6;
例子:
include <stdio.h>
int main (void)
{
int a[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
}
for (int i=0; i<3; i++)
{
for (int j=0; j<4; j++)
{
printf(“%-5d”a[i][j]);//负表示左对齐,5表示5个空格
}
printf(“\n”)
}
return 0;
}
9.3 多维数组
不存在,因为内存是线性一维的,n维数组可以当做每个元素是n-1维数组的一维数组
比如: int a[3][4];
该数组是含有3个元素的一维数组,只不过每个元素都可以再分成4个小元素
int a[3][4][5];
该数组是含有3个元素的一维数组,只不过每个元素都是4行5列的二维数组
函数【C语言的第二个重点】
为什么需要函数
避免了重复性操作
有利于程序的模块化
10 什么叫函数
逻辑上:能够完成特定功能的独立的的代码块
物理上:
能够接收数据【当然也可以不接收数据】
能够对接收的数据进行处理
能够将数据处理的结果返回
总结:函数是个工具,它是为了解决大量类似问题二设计的函数
include <stdio.h>
int f(void) //括号中void表示该函数不能接受数据,int 表示函数的返回值是int类型
{
return 10; //向主调函数返回10
}
int main(void)//
{
int j = 88;
j =f(); //j 的值又变成了10
printf(“%d\n”, j);
return 0;
}
10.1 如何定义函数
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
1、函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法
2、return 表达式的含义:
1>终止被调函数,向主调函数返回表达式的值
2>如果表达式为空,则只终止函数,不向被调函数返回任何值
3>break是用来终止循环和switch,return是用来终止函数的
例子:
void f()
{
return ;//return只用来终止函数,不向主调函数返回任何值
}
int f()
{
return 10; //第一:终止函数,第二:向主调函数返回10
}
3、函数返回值的类型也称为函数的类型,因为如果 函数名前的返回值类型和函数执行体中的return 表达式中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准,。【返回值的类型也就是该函数的类型】
例子:# include <stdio.h>
int f()
{
return 10.5;//返回的值为10,因为函数的类型为int类型
}
int void main(void)
{
int i = 99;
double x = 6.6;
x = f();
printf(“%lf\n”, x);
return 0;
}
例子:判断两个数的大小
include <stdio.h>
int max(int i, int j)
//max 是函数的名字i和j是形式参数,简称 形参,void表示函数没有返回值 函数调用完毕后,为i , j分配的空间立即被释放。再次调用函数时,i和j分配的空间不一定跟上次调用分配的空间相同。
{
if(i>j)
printf(“%d\n”, i);
else
printf(“%d\n”, j);
}
int void main(void)
{
int a, b;
printf(“请分别输入两个数\n”);
scanf(“%d”, &a);
scanf(“%d”, &b);
printf(“最大的那个数为\n”);
max(a, b);
reurn 0;
}
程序从main函数开始,从main函数结束
函数的分类
有参函数 和 无参函数
有返回值函数 和 无返回值函数
库函数 和 用户自定义函数
值传递函数 和 地址传递函数 //有待进一步考虑
普通函数 和 主函数 (main函数)
一个程序必须有且只能有一个主函数
主函数可以是调用普通函数 普通函数不能调用主函数
普通函数之间可以相互调用
主函数是程序的入口,也是程序的出口
#include <stdio.h>
void max1(int i, int j)
{
if(i > j)
printf(“%d\n”, i);
else
printf(“%d\n”, j);
}
int max2(int i, int j)
{
if(i > j)
return i;
else
return j;
}
int main(void)
{
int a = 1, b = 2, c = 3, d = 9, e = -5, f = 100;
printf(“%d\n”, max2(a, b));
max1(a, b);
return 0;
}
判断一个数是否为素数
#include <stdio.h>
int main(void)
{
int val, i;
scanf(“%d”,&val);
for(i=2; i<val; i++)
{
if(val%i == 0)
break;
}
if(i == val) //说明val没有除尽2~val之间的任意一个数
printf(“是素数”);
else
printf(“不是素数”);
return 0;
}
使用函数:
#include <stdio.h>
bool IsPrime(int val)
{
int i;
for(i=2; i<val; i++)
{
if(val%i == 0)
break;
}
if(i == val) //说明val没有除尽2~val之间的任意一个数
return true;
else
return false;
……… //一旦执行return 后面的均不再执行
}
int main(void)
{
int m;
scanf(“%d”,&m);
if(IsPrime(m))
{
printf(“是素数”);
else
printf(“不是素数”);
}
return 0;
}
浮点数的存储所带来的问题
Float 和double都不能保证可以把所有的实数都准确的保存在计算机中
因为浮点数无法准确存储,所以就衍生出来两个编程问题
例子
float I = 99.9;
printf(“%f\n”, i);
最终在Vc++6.0中的输出结果是:99.900002
if(|x-0.000001| <= 0.000001)
是零;
else
不是零;
函数的声明
#include <stdio.h>
void f(void); //函数声明,分号不能丢
int main(void)
{
f(); //函数的调用
return 0;
}
void f(void) //函数的定义
{
printf(“hello!\n”);
}
#include <stdio.h>
void f(void) //函数的声明加定义
{
printf(“hello!\n”);
}
int main(void)
{
f(); //函数的调用
return 0;
}
有函数声明时,函数声明必须放在函数调用的前面,函数的定义可放在函数调用的前面也可放在函数调用的后面;无函数声明时,函数的定义(声明)必须放在函数调用的前面
注意的问题
函数调用和函数定义的顺序
如果函数调用写在了函数定义的前面,则必须加函数前置声明
函数前置声明:
1、告诉编译器即将可能出现的若干个字母代表的是一个函数
2、告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况。
3、函数声明是一个语句,末尾必须加分号
4、对库函数的声明是通过#include<库函数所在的文件的名字.h>来实现的
形参和实参
个数相同 位置一一对应 数据类型必须相互兼容
C语言常用的系统函数
double sqrt(double x); 求x的平方根
int abs(int x); 求x的绝对值
double fabs(double x) 求x的绝对值
10.2 变量的作用域和存储方式
全局变量
在所有函数外部定义的变量叫全局变量
全局变量使用范围:从定义位置开始到整个程序结束
局部变量
在一个函数内部定义的变量或者函数的形参,都统称为局部变量
void f(int i)
{
int j = 20;
}
i和j都属于局部变量
局部变量的使用范围:只能在本函数内部使用
注意的问题:
全局变量和局部变量命名冲突的问题
#include <stdio.h>
int i = 99;
void f(int i)
{
printf(“i = %d\n”, i);
}
int main(void)
{
f(8)????/8
return 0;
}
在一个函数的内部如果定义的局部变量的名字和全局变量的名字一样=时,局部变量会屏蔽掉全局变量
按变量的存储方式
静态变量
自动变量
寄存器变量