看似没有问题,注意到一个细节没有?在第一个printf()的最后多了一个","。虽然有些编译器,例如GCC并不会计较(也许就是一个warning),但对于广大洁癖严重的处女座程序员来说,这怎么能忍,于是在ANSI-C99标准引入可变参数宏的时候,又贴心了加了一个不那么起眼的语法:当下面的组合出现时 ",##__VA_ARGS__",如果__VA_ARGS__是一个空字符串,则前面的","会一并被删除掉。因此,上面的宏可以改写为:
#define log_info(__STRING, ...) printf(__STRING,##__VA_ARGS__)
一 格式问题(小白起步阶段)
# include <stdio.h> 前面的 <前面需要一个空格
一行只定义一个变量,同一类型放一起,末尾的的分号;前不需要空格
已初始化的变量放一个区域,未初始化的变量放一个区域写
printf,scanf和()之间不需要空格
if(){}的中括号需要换行
自定义的函数放main前,函数的中括号换一次行
二 格式化输出与输入(printf,scanf)
(1) printf(“格式控制串”, 输出表达式);
注意格式控制符的使用:
%d 十进制
%i 十进制整数
%hd 短整型
%x 十六进制整数
%o 八进制整数
%u 无符号十进制整数
%c 单个字符
%s 字符串
%e 指数形式浮点数
%f 小数形式浮点数
%g 指数小数里取表达的最短形式展示 即哪个格式表达短 就展示哪个形式
%p 变量的内存地址
int型数组长度确认 sizeof(array)/ sizeof(int)
小知识点 数组名保存着数组首元素的地址
思考题:
{
printf (“hello,world”);
while (1);
return 0;
}
的结果真的是打印句子然后一直循环么~
提示 “hello,word!\n ”才可以打印 或者 不加 ‘’\n‘’ 后一行为 scanf 也行
解释
因为 scanf 和 printf 是同一个缓冲区,scanf 会先把缓冲区刷出来,再输入,所以缓冲区被强行输出。 所以 目前用 printf 一定加 ‘\n’ ,确保信息可以输出
重点知识扩展
printf 是行缓冲 满一行(一行缓冲区默认大小4096个字符,满后输出)或者遇到 斜杠n 或者缓冲区被强行刷出时,数据才会被输出
printf 新大陆(使用技巧)
printf (“\033[字背景色;字体色m字符串\033[0m”); 可以个性化打印字符
如 printf ("\033[38;38mhello,world\033[0m');
(2) scanf 注意事项
1 格式化输入 遇空格停止
如 scanf("num = %d", &num);
输入时需要输入 “num = 数值” 才能成功
2 scanf 不要加 斜杠n ‘\n’ 会导致输入问题 而后面是变量的地址 记得加上 &
3 scanf 产生垃圾
scanf 表示输入字符时遇到输入不了 在前一行加上 getchar()有奇效~~~
或者写成 (" %c", &ch) 空格+百分号c ("%*c%c", &ch) 百分号星c百分号c
小知识
字符串的输入输出可以使用 gets() 和 puts()
但是要注意 gets 是无缓冲的 当输入超过数组大小 会造成数组越界 一旦空间不够 内存里运行的程序很多时 这时数据会出现问题
三 运算符与表达式
1 自增 自减运算符
注意标准
i++ 是以当前运算结束为标准后自加1
c语言运算结束标志 分号;逗号,括号()函数 (其实可以看成())
如:int num = ( ++i )+ ( ++i )+ ( ++i )+ ( ++i );
注意 + 是双目运算符 即同时左右两边运算
所以分析如下 :
从左至右 先 i = i + 1
i = i + 1;
相当于先 num = ( i+2 )+ ( i+2 )
再 num = num + ( i + 3 )= 13
再 num = num + ( i + 4)= 19
2 函数类型的自增自减
注意
(1) 函数传参从最右边开始 因为是用栈来保存的
(2)函数里的 ++i 在运算中先统一替换成变量名,即 i
(3) i++ 被替换成运算中即时得出的值 举例
如
int i = 2;
func ( i ++ ,++ i );
运算中相当于 func ( 3,i )
最后将 i = i + 2 的值带入到 i 中
指针类型的自增自减问题
注意func ( *ptr,*( ptr ++),*( ++ptr ),*( ptr++ ),*( ++ptr ));
因为取了值就会打印出来 所以 ++ptr 不适用最后替换变量原则 直接从右往左正常打印
指针类型疑问 (ptr指针为常量 所以应该不能自增自减 可是老师这么演示了 欢迎各位大大指正)
3 逻辑运算符
短路与,半开与或的问题
即 只要前半部分逻辑成立 后半部分则不去判断
如
int i = 2;
int j = 3;
if ( 2 == i || j++ )
{
}
printf("j = %d\n", j);
return 0;
结果是j为3 j++ 没有执行
同理 接上
if ( 4 == i || j ++ )
j为4
if( 4 == i && j ++ )
j为3 j++ 不处理 因为1条件为否 2条件就不看了
位运算
& 按位与
| 按位或
^ 按位异或 (相同为0,相异为1)
~ 按位取反
>> 按位右移
<< 按位左移
保留:与相应位全为1的二进制数相与
如 1010 1100 保留低位的两个1
则与 0000 1100 相与
注 这里的 0000 1100 我们称之为掩码
清零 : 相应位与相应位全为0其余位为1的相与 即掩码的反码
如 1010 1100 把低位的1清零
即与 1111 0011 相与
置位 即相应位全部置1 与掩码相或
如 1010 1100 把低位0置1
即与 0000 0011 相或
取反 相应位与掩码异或
如 1010 1100 把低位1取反
即与 0000 1100 异或