[C大程]考试复习笔记

本文详细介绍了C语言中的输入输出函数scanf和printf的使用,包括如何处理空白、如何读写字符串、数组以及指针。还探讨了预处理指令、函数、变量的作用域和生存期,以及结构体和数组的相关知识。对于初学者,这是理解C语言基本输入输出和控制结构的重要参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

scanf

吃空白,也就是把空格、回车、制表符全都吃掉

scanf()默认把空白作为分割多个输入的标志,所以当你输入空白的时候,scanf()会认为你将要进行下一个输入,从而停下来等你输入下一个非空白数据。但是,当参数字符串的处理已经来到结尾或者输入流来到末尾的时候,scanf()不会认为你将继续进行输入,也就不会进行“吃空白”行为,这也是为什么会剩下一个’\n’的原因。所以参数为"%d"的时候直接输入然后按回车就结束了。

当参数为"%d   "的时候,此时没有处理到结尾,scanf()会认为你要继续进行输入。然而你输入了空格或者回车,scanf()认为他们是分隔符,于是“吃空白”吃掉了。换句话来说,scanf()依旧在等待你的输入,只有当你输入不是空白的字符以后,scanf()才会用它与参数字符串里面的空格比较。

scanf以空格、制表符、换行符和结束符EOF伟输入结束标志,当读入%s时,不允许有空格

其前可以加数字表明占有的位数,系统会自动截取

%*3d 带*表示本输入项输入后不传给任何量储存

字符数组名是地址常量,scanf中不用加&

scanf(“%d  %s”,&a,&b);是可以的

如果需要在scanf后再读入一个字符

scanf("%s",a);
getchar();跳过分隔符
ch=getchar();

gets(),puts()换行符、文件结束EOF为输入的结束标志

printf

如果是输出数组,记得带*

sizeof(),返回字节长

strlen(),有效字符个数

单引号  \'    双引号   \''

运算顺序:单算移关位逻

结构运算符号 . ->的优先级超高

&&||得出结论后左边不会再执行

赋值右结合

switch(不是整数自动取整){
    case 常量:~;
              ~:
             break;
    ....
    default:....
    }

case后只能是常量,不能有变量或者函数(即使已经赋值)

如果无break,将执行之后的所有语句

case和default后的复合语句可以不用大括号哦

数组

数组名指向的地址不能修改

二维数组

定义a[1][1]

a和*a的内容是同一个地址,但是意义不同

char a[3][5];

数组a的3*5个数组元素在内存中是连续存储的

 上图中每一个格子表示一个char型的数组元素。因此二维必须知道列数

char a[3][5];
char *p = a[1];
printf(“%d”, *(p + 2));
printf(“%d”, p[2]);
a[1]的表达式只是一个指针(a[1]不能被赋值),可以像使用指针一样使用

指针

s+1:指针向后移1单位(char、int、double...视指针类型)

指针数组/指向数组指针

int *a[10]  指针数组,每个元素都是一个指针;a是数组名
int (*a)[10]  数组指针,该指针指向一个int型有10个元素的数组;a是指针名
        int a[97];
        int (*p)[97] = &a;	*p将得到一个“int [97]数组”,*(p+1)的值是指向数组a最后一个元素后面的位置,和&a[97](越界)的值是一样的。

虽然指针的指针与数组指针均是二级指针,但它们的 类型不同 ,不能相互赋值。
数组的指针指向的是一个 数组 注意是数组整体,而非数组首元素

二级指针

二级指针存的是一个一级指针的地址

int **p 可以用二维数组来理解
二级指针指向一级指针的地址(不是指针内容的地址。指针和它的内容不在同一个地方)

结构

(*结构指针).成员
结构指针->成员

全局变量

如果没有指定初值,为系统默认值(int为0,float和double为0.0,char为'\0',指针为NULL)

与局部变量冲突时,局部变量起作用

只能定义一次。extern只是声明,不再分配空间

外部声明(另一个文件中),(extern) int f(形参表)

静态变量

整个程序结束后才释放,static,extern

未赋初值,值为系统默认值

静态全局变量作用域被限制在该文件,其他文件即使声明extern也不能用

多个文件中都要用到同一个外部变量时,如果在多个文件中定义,会出现重复定义的错误,正确的做法是:在一个文件中定义,其他文件中用 extern声明一下

动态变量

所在函数结束后立刻释放,函数的形参,auto(自动,缺省),register(寄存器;现在的系统会把常 

       用的变量自动分配为寄存器变量,实际应用时register就不用声明了)

未赋初值,值不确定

函数

函数不可以嵌套定义,但可以嵌套调用

声明函数时,可以省略形参名字(但不可省略参数类型)

参数传递

int a    复制
int *a   给地址
int &a   给本身

函数指针(注意括号哦)

已有 void funone(int a, char b);
     
声明:void(*p)(int a,char b);     类型(指针)(形参表)
      p=funone;
调用 (*p)(a,b)    
    如   int funtwo(int c,void(*p)(int a,char b);

内部函数

static int function(   ):
1个函数只能在所定义的源文件中被调用

外部函数

用extern声明就可以直接在另一个文件中用(允许声明的时候省略extern)

预处理→编译→汇编→连接→生成可执行文件

预处理(#开头,不需要

1.宏定义

#define 出现在函数外部,有效范围为从定义位置到 #undef或者文件结束
只做字符替换,不占用内存

2.文件包含

#include“文件名”
先在源文件同目录中找,找不到再按系统的标准方式,直到找到;通常用于自己编的文件
#include<文件名>
只按标准方式去找(include文件夹)

 使用文件包含时,被包含文件中不能有main(),被包含文件的全局变量只在该文件有效

3.条件编译

主要是适应不同系统条件的兼容问题,有三种格式
#ifdef标识符(若标识符定义过,编译1) 或 #ifndef(未定义,则)
    程序1
(#else
    程序2)
#endif


#if表达式
    程序1
#else
    程序2
#endif
注意这个不同与普通的if-else,这个只有一部分会生成到目标代码中

类型定义typedef

习惯上把新类型名定义为大写字母,定义后原有类型名仍然有效

typedef int*p       p是指向int类型的指针
tppedef int(*p)[10] p是一个由10个元素的数组指针

typedef   char*  string;
       	string  p1;       <====>    char  *p1; 
    相当于把p1带入到上面string的位置

中文需要占两个char

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值