C语言编程常见技巧(问题???)
本文章根据《算法竞赛入门经典(第二版)》一书整理。。。
第一章 程序设计入门
- printf 语句控制输出小数位数或总长度
printf("%.3f\n",8.0/5.0) //小数位数为3。
printf("%.*f\n",3,8.0/5.0) //用3来代替* ,用来动态指定小数位数
printf("%3d",xxx) //指定输出宽度为3
printf("%-3d",xxx) //左对齐,邮编填补空格
printf("%03d",xxx) //指定宽度,并用0填补左边空缺
- 求多位数各个位上的数
while(x > 0){
y = x % 10; //y分别为个位、十位、百位等
x /= 10;
}
- 交换变量a,b的值
方法一:借用第三方变量
int a,b,temp;
temp = a;
a = b;
b = temp;
方法二:不借用第三方变量
1)使用加减法(和不变)//限制:只有定义了加减法的数据类型才可以使用。
int a,b;
a = a +b;
b = a - b;
a = a - b;
2)使用异或运算(^)
a = a ^ b;
b = a ^ b;
a = a ^ b;
原理: x^x == 0; x^0 == x;
首先用a保存了a^b的值,再用b = a ^ b = (a^b)^b=a^b^b=a^(b^b)=a^0=a,这样实现了b = a;
接着又用a = a^b = (a^b)^b(第一个b还是原来的b,而第二个b已经是a的值)= (a^b)^a = a^a^b = 0^b = b,这样实现交换。
- C语言中,0为假,其余皆为真。
第二章 循环结构程序设计
- 四舍五入
floor(x + 0.5)
- continue和break
continue进行下一次循环。break则是跳出当前循环体。
- 整数溢出
int型一般为32位整数,取值范围为-2^31~2^31-1,即-2147483648~2147483647
- while (先判断后计算)
- do while (先计算一次,后判断)
- scanf判断输入结束:
windows:输入完毕后,先按Enter键,再按Ctrl+Z键,最后在按Enter键。之所以这么复杂是因为scanf语句的输入格式中空格,TAB,回车符都不意味着输入结束。
Linux:输入完毕后按下Ctrl+D即可。
while(scanf("%s",&a) == 1 ) //保证输入不为空(有没有==1,意义不大吧。。。。)
while(~scanf("%d",&m,&n)) 等同于:while (scanf("%d%d",&m,&n)!=EOF)
//参考:https://www.cnblogs.com/woaiheniunai/p/6394672.html
//EOF定义为-1。~是按位取反,-1十六进制补码表示为0x ffffffff,f是二进制的1111,取反后就全部变成0了,于是while结束。 //限制:仅用于输入数字(字母、符号容易形成死循环)。
while(scanf("%d",&a) == 1 && n) //保证输入不为空且不是0。
while(scanf("%d",&s) == 1) 按下Ctrl+z +回车 即可结束输入。但while(scanf("%d",&s) != '\n')或while(scanf("%d",&s) != EOF)是不可以。。。未解决。
- 文件读取
输入输出重定向:详见https://blog.csdn.net/xavierdarkness/article/details/80638641;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
文件读取(不使用重定向)(较灵活)
FILE *fin,*fout;
fin = fopen("data.in","rb");
fout = fopen("data.out","wb");
不同:freopen不是指针类型的,写起来简单,自然,但不可同时读写文件和输入输出。
fopen则需使用文件指针,且在使用fopen时,应使用配套的fsacnf和fprintf进行输入输出,普通的scanf和printf依然能在命令行界面操作。
如果在fopen下想使用标准输入输出,只需赋值“fin = stdin;fout = stdout”即可,此时不在调用fopen和fclose。
- 浮点数溢出
在除法中(1/n^2)此时,需注意溢出,此时要使用连除(1/n/n)而不是直接除以其平方和(1/(n*n))。
第三章 数组和字符串
- 数组声明:
数组在程序中的声明位置很重要:参考:https://zhidao.baidu.com/question/397529275.html。
全局变量(在main函数外声明)在静态存储区分配内存,局部变量(main函数内声明)是在栈上分配内存空间的,
VC堆栈默认是1M,int a[1000000]的大小是4*1000000,将近4M,远远大于1M,编译连接的时候不会有问题,但运行是堆栈溢出,程序异常终止。
- 内存复制:#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
常用方法:把数组a全部复制到数组b中:memcpy(b,a,sizeof(a));
- 数组置零:#include <string.h>
void *memset(void *s, int ch, size_t n);
函数说明:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s。
常用方法:将数组a清零:memset(a,0,sizeof(a));
- 开关问题
一般使用j % i 来判断几倍关系,用 !来取反模拟实现开启、关闭。
- 蛇形填数(1)
eg:10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
类似上述问题使用数组,模拟笔撞墙(是否越界、是否填过)的问题。
检验是否填过以及碰壁:(碰壁条件 && !a[x][y])而不是判断(a[x][y] == 0)。
- scanf注意事项与gets (#include <stdio.h>)区别: 参考:https://zhidao.baidu.com/question/290403568.html.
1、 gets功能为读入一行,并将换行符(\n)转换为字符串结束符(\0)。
2、 scanf("%s",s);读入时,遇到空白字符,包括空格,制表符,换行符时均会停止输入。
对于字符串数组scanf("%s",s)和scanf("%s",&s)是没有区别的,s代表数组首地址,&s也是一样。
对于字符(int型或其他)来说参考以下:
scanf
函数要求第二个参数是一个指针类型的变量
scanf
(
"%d"
,a)----->表示a的定义为:
int
* a;
scanf
(
"%d"
,&a)---->表示a的定义为:
int
a;
3、终止条件不同。
gets只有遇到\n时才会结束输入,而scanf遇到空格或制表符时,也会结束输入。
比如输入"test string\n"。
用gets得到的字符串为"test string", 二用scanf得到的是"test"。
4、终止后,对终止字符处理不同。
比如输入为"test\nabcd"。
执行gets后,\n不会留在缓冲区中,即这时调用getchar得到的字符是'a'。
执行scanf后,\n会留在缓冲区,这时调用getchar得到的字符是'\n'。
- sprintf (#include <stdio.h>)参考:https://baike.baidu.com/item/sprintf/9703430?fr=aladdin。应保证写入的字符串有足够的空间。
作用:把格式化的数据写入某个字符串缓冲区。
int sprintf( char *buffer, const char *format, [ argument] … );
返回值:返回写入buffer 的字符数(\n计算在内,\0不计算在内),出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL(不懂)。
用例:
char buffer[200], s[] = "computer";
int j;
j = sprintf( buffer, "%s\n", s ); //此时buffer为“computer”,j为9(8+1)。
- sizeof和strlen (#include <string.h>)的区别:参考:https://www.cnblogs.com/carekee/articles/1630789.html
sizeof为运算符其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
strlen(...)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。
- strchr:(#include <string.h>) 参考:https://baike.baidu.com/item/strchr/10985184?fr=aladdin
char *strchr(const char* _Str,char _Val)
功能:查找字符串_Str中首次出现字符_Val的位置。
说明:返回首次出现_Val的位置的指针,返回的地址是被查找字符串指针开始的第一个与Val相同字符的指针,如果Str中不存在Val则返回NULL。
- fgets (#include <stdio.h>) 参考:https://baike.baidu.com/item/fgets/10942211?fr=aladdin。
char *fgets(char *buf, int bufsize, FILE *stream);
参数:
*stream: 文件结构体指针,将要读取的文件流。
返回值:
- 成功,则返回第一个参数buf;
- 在读字符时遇到end-of-file,则eof指示器被设置,如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL;
- 如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变。
注意:从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize-1个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。
- fgetc (#include <stdio.h>) 参考:https://baike.baidu.com/item/fgetc/10942198?fr=aladdin。
int fgetc(FILE *stream);
功 能:从流中取字符。
fgetc()从参数stream所指的文件中读取一个字符,并把它作为一个字符返回。若读到文件尾或出现错误时,它就返回EOF(-1),你必须通过ferror或feof来区分这两种情况。
- getc (#include <stdio.h>)参考:https://baike.baidu.com/item/getc/919590?fr=aladdin。
int getc(FILE *stream);
功 能:从流中取字符。
返回值:从文件指针stream指向的文件流中读取一个字符,并把它作为函数值返回给整型变量ch,并把位置标识符往前移动。
- getchar (#include <stdio.h>) 参考:https://www.cnblogs.com/try-again/p/4975802.html。
int getchar(void);
参数:该函数没有参数。
返回值:函数的返回值为用户输入的第一个字符的ASCII码,若出错返回-1,且将用户输入的字符回显到屏幕。如果用户在按回车键之前输入了不只一个字符,其他字符会保留在键盘缓冲区中, 等待后续getchar()调用读取。也就是说,后续的getchat()调用不会等待用户按键,而是直接读取缓冲区中的字符,直到缓冲区的字符读取完毕后,才等待用户按键。
- 键盘输入错位问题(字符串常量数组)UVa10082 WERTYU
方法一:(原著)使用的是先使用for( i = 1; s[i] && s[i] != c;i++);来获取当前输入字符位置,然后减一就是正确位置。
方法二:使用strchr获取字符串位置。详见https://www.cnblogs.com/BANLOONG/p/10389951.html。
- isalpha (#include <ctype.h>) 参考: https://baike.baidu.com/item/isalpha/387277?fr=aladdin。
int isalpha( int ch )
功能:断字符ch是否为英文字母
返回值:若为英文字母,返回非0(小写字母为2,大写字母为1)。若不是字母,返回0。
- isdigit (#include <ctype.h>) 参考:https://baike.baidu.com/item/isdigit/9455880?fr=aladdin。
功能:用于检查其参数是否为十进制数字字符。
返回值:若参数c为阿拉伯数字0~9,则返回非0值,否则返回0。
- isprint(#include <ctype.h>)参考:http://c.biancheng.net/cpp/html/119.html。
功能:判断字符c是否为可打印字符(含空格)。
返回值:当c为可打印字符(0x20-0x7e)时,返回非零值,否则返回零。
注意:判断字符c是否为可打印字符(含空格)说明:当c为可打印字符(0x20-0x7e)(ACSII中对应' ' 到 '~')时,返回非零值,否则返回零。0x7f(DEl)为控制字符,用iscntrl函数判断。
- iscntrl (#include <ctype.h>) 参考:http://c.biancheng.net/cpp/html/115.html。
功能:用来判断字符是否为ASCII码的控制字符。
返回值:若参数c 为ASCII 控制码,则返回非 0 值,否则返回 0。
注意:控制字符的ASCII码值 0x00 ~ 0x1F,再加上 0x7f(DEL),控制字符在屏幕上显示时不占位(看不见);
- 回文(aba)+镜像(5↔Z)问题 :UVa401 Palindromes
用两个标志位分别代替是否回文和是否镜像,共四种结果,此时可以使用数组来保存这四种结果,输出时由两个标志位计算即可得出结果
eg:char *msg[] = {"非回文","回文","镜像","镜像+回文"}
p = 0; //不是回文 m = 0; //不是镜像
printf("%s",msg[m*2+p]);
注意:字符数组顺序需注意匹配结果。
- 猜数字问题:UVa340 Master-Mind Hints 参考:https://blog.csdn.net/weixin_39274830/article/details/79179057。
给定答案序列和用户猜的序列,统计有多少数字位置正确(A),有多少数字在两个序列都出现过但位置不对(B)。
//直接统计得A,为了求B,对于每个数字(1—9),统计二者出现的次数c1和c2,则min(c1,c2)就是该数字对B的贡献,最后要减去A的部分。
同一数字c1和c2都存在(一次都没有出现记为0),证明该数字在两个序列中皆出现过,但此时的出现包括两种情况(位置正确的(即A)和不正确的(即B)),而如下例eg1中的d=3,c1=1,c2=0,说明该数字在b[i]中没有出现,当然不计入A或B中,同理,eg2中的d=6,c1=0,c2=2,说明该数字在a[i]中不存在,同样不计入A或B。
eg1:a[i] 1 3 5 5 5
b[i] 5 5 2 6 6
eg2: a[i] 1 3 2 5 5
b[i] 5 5 5 6 6
在d=5时,eg1中c1为3,c2为2,c1>c2,在最好的情况下,b[i]中的2个5位置都正确,
eg2中,c1为2,c2为3,c1<c2.在最好的情况下,也只有2个5满足条件,因此总的来说,就是取较小值。(自己掰的)。
for(;;){
int A=,B=;
用for循环直接比较得出A; //伪代码
结束输出; //伪代码
for(int d=;d<=;d++){ //统计数字d(1~9)在答案序列a[i]和猜测序列b[i]中各出现次数。
int c1=,c2=;
for(int i=;i<n;i++){
if(a[i]==d) c1++;
if(b[i]==d) c2++;
}
if(c1<c2) B+=c1; //取两序列中较小者,
else B+=c2;
}
}
- 环状序列 UVa 1584,ACM/ICPC Seoul 2004 ,Circular Sequence
任意字符串按字典序比较(选较小者):
int less(char *s, int p, int q){ // 比较两个序列的字典序(p表示法是否比q表示法小)
int n = strlen(s);
for(int i = ; i < n; i++ ){
if(s[(p+i)%n] != s[(q+i)%n])//意味着元素相同时候继续 直到有不同的元素为止
return s[(p+i)%n] < s[(q+i)%n];//不同时直接返回 大小关系
}
return ;//到这一步 说明这两个序列 元素一样
}
注: “%n”可以保证整个字符全部取到。如下,p=2时,使用“%n”可以实现即使将“A”为首,认可读到“A”前的“CT”,这样读取到的就是下列表格中的结果。
eg:CTAC
------------------------------------------------------------------------------------------------------------23:13:18 2019-02-18
- 判断素数(质数)
int is_prime(int i){
for (int j = ; j * j <= i; j++)
if(i % j == )
return ;
return ;
}
- 求最大公约数(辗转相除法)
int max_n(int a,int b){
if(a > b){
if (a % b == )return b;
else{
a -=b;
max_n(a,b);
}
} else{
int temp = a;
a = b;
b = temp;
max_n(a,b);
}
}
最小公倍数为二数之积除以最大公约数。
C语言编程常见技巧(问题???)的更多相关文章
- R语言编程中的常见错误
R语言编程中的常见错误有一些错误是R的初学者和经验丰富的R程序员都可能常犯的.如果程序出错了,请检查以下几方面. 使用了错误的大小写.help().Help()和HELP()是三个不同的函数(只有第 ...
- 一些有意思的面试题(持续更新) .C语言编程技巧札记
一些有意思的面试题(持续更新) http://blog.csdn.net/wangyuling1234567890/article/details/38565239 C语言编程技巧札记 http:// ...
- 你可能不知道的30个Python语言的特点技巧
1 介绍 从我开始学习Python时我就决定维护一个经常使用的“窍门”列表.不论何时当我看到一段让我觉得“酷,这样也行!”的代码时(在一个例子中.在StackOverflow.在开源码软件中,等等), ...
- 30 个 Python 语言的特点技巧
1 介绍 从我开始学习Python时我就决定维护一个经常使用的“窍门”列表.不论何时当我看到一段让我觉得“酷,这样也行!”的代码时(在一个例子中.在StackOverflow.在开源码软件中,等等 ...
- 个人c语言编程风格总结
总结一下我个人的编程风格及这样做的原因吧,其实是为了给实验室写一个统一的C语言编程规范才写的.首先声明,我下面提到的编程规范,是自己给自己定的,不是c语言里面规定的. 一件事情,做成和做好中间可能隔了 ...
- 提高php编程效率技巧
提高php编程效率技巧 投稿:mrr 字体:[增加 减小] 类型:转载 时间:2015-08-13 php是全球范围应用范围最广的开发语言,php和linux.apache.mysql紧密结合,形 ...
- 第二章 C语言编程实践
上章回顾 宏定义特点和注意细节 条件编译特点和主要用处 文件包含的路径查询规则 C语言扩展宏定义的用法 第二章 第二章 C语言编程实践 C语言编程实践 预习检查 异或的运算符是什么 宏定义最主要的特点 ...
- 你可能不知道的 30 个 Python 语言的特点技巧
列表按难度排序,常用的语言特征和技巧放在前面. 1.1 分拆 >>> a, b, c = 1, 2, 3>>> a, b, c(1, 2, 3)> ...
- 华为C语言编程规范
DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...
随机推荐
- Zabbix监控进程(进程消失后钉钉报警)
用于python报警的脚本如下:(钉钉机器人的连接需要修改) #!/usr/bin/python3# -*- coding: utf-8 -*-# Author: aiker@gdedu.ml# My ...
- 从OsChina Git下载项目到MyEclipse中
前提是,拥有权限下载 1.进入MyEclipse,点击File-->Import,选择Git,点击“Next”,如下图: , 2.选择“URI”,点击"Next" 3.输入项 ...
- 使用redis-cli --pipe快速插入数据
具体实现步骤如下:(参考http://www.cnblogs.com/ivictor/p/5446503.html) 1. 新建一个文本文件redis_commands.txt,包含redis命令 S ...
- rpc调用过程
在openstack中,各个组件之间的调用遵循RESTful风格,而组件内部各服务之间的相互调用采用rpc远程调用,比如nova-conductor和nova-compute rpc原理: 首先了解什 ...
- Linux 查看内存使用情况
1 . top : 用于实时显示 process 的动态 PID:进程的ID USER:进程所有 PR:进程的优先级别,越小越优先被执 VIRT:进程占用的虚拟内 RES:进程占用的物理内 SHR: ...
- Linux 查看各文件夹大小命令du -h --max-depth=1
du [-abcDhHklmsSx] [-L <符号连接>][-X <文件>][--block-size][--exclude=<目录或文件>] [--max-de ...
- leetcode155
public class MinStack { Stack<int> S = new Stack<int>(); /** initialize your data struct ...
- 30个php操作redis常用方法代码例子(转载)
1.connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE示例: $redis = new red ...
- C++ queue
queuequeue 模板类的定义在<queue>头文件中.与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选 ...
- [Solution] 950. Reveal Cards In Increasing Order
Difficulty: Medium Problem In a deck of cards, every card has a unique integer. You can order the de ...