C语言tips

本文介绍了C语言中的多种编程技巧,包括变量类型与输出格式、逻辑运算符、循环结构、时间测量方法、数组处理及字符串操作等内容。此外还讨论了如何避免变量溢出问题,以及在函数调用和内存管理方面的一些注意事项。

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

  • 整数值用%d输出,实数用%f输出、
  • 整数/整数=整数,浮点数/浮点数=浮点数。 printf(“%.1f\n”, 8.0/5.0); /输出0.0*************/
  • scanf中的占位符和变量的数据类型应一一对应,且每个变量前需要加“&”符号
  • 赋值a=b之后,变量a原来的值被覆盖,而b的值不变
  • if语句的条件是一个逻辑表达式,它的值可能为真,也可能为假。单个整数值也可以表示真假,其中0为假,其他值为真。
  • C语言中的逻辑运算符都是短路运算符。一旦能够确定整个表达式的值,就不再继续计算
  • scanf、空格、TAB和回车符的过滤
  • for循环的格式为:for(初始化;条件;调整)循环体;
  • 建议尽量缩短变量的定义范围。例如,在for循环的初始化部分定义循环变量 for(int a = 1; a <= 9; a++)
  • 可以使用time.h和clock()函数获得程序运行时间。常数 printf(“Time used = %.2f\n”, (double)clock() / CLOCKS_PER_SEC);
  • 本题中n的上限109只比int的上界稍微小一点,因此溢出了也并不奇怪。只要使用C99中新增的long long即可解决问题,其范围是-263~263-1,唯一的区别就是要把输入时的%d改成%lld。但这也是不保险的——在MinGW的gcc(7)中,要把%lld改成%I64d,但奇怪的是VC2008里又得改回%lld。是不是很容易搞错?所以如果涉及long long的输入输出,常用C++的输入输出流或者自定义的输入输出方法
  • int c[10] = {1}; /* 只对c[0]赋了1,其它都还是零 ***/
  • 复制时要写成“memcpy(b,a,sizeof(double)*k),如果需要把数组a全部复制到数组b中,可以写得简单一些:memcpy(b,a,sizeof(a))。memset(a,0,sizeof(a))”的作用是把数组a清零,它也在string.h中定义 头文件一定要包含string.h 或者 cstring, 没用
  • cout<< setw[3]<< a[i][j];要包含头文件 < iomanip >
  • 另一个新内容是“scanf(“%s”, s)”。和“scanf(“%d”, &n)”类似,它会读入一个不含空格、TAB和回车符的字符串,存入字符数组s。注意,不是“scanf(“%s”, &s)”,s前面有“&”符
  • 在“scanf(“%s”, s)”中,不要在s前面加上“&”符号。如果是字符串数组chars[maxn] [maxl],可以用“scanf(“%s”, s[i])”读取第i个字符串。注意,“scanf(“%s”, s)”遇到空白字符会停下来。
  • 函数strlen(s)的作用是获取字符串s的实际长度。什么叫实际长度呢?字符数组s的大小是
  • 但并不是所有空间都用上了。如果输入是“2357”,那么实际上s只保存了5个字符(不要忘记了还有一个结束标记“\0”),后面15个字符是不确定的(还记得吗?变量在赋值之前是不确定的)。strlen(s)返回的就是结束标记之前的字符个数。
  • 由于字符串的本质是数组,它也不是“一等公民”,只能用strcpy(a, b),strcmp(a, b), strcat(a, b)来执行“赋值”、“比较”和“连接”操作,而不能用“=”、“==”、“<=”、“+”等运算符。上述函数都在string.h中声明
  • 从标准输入读取一个字符可以用getchar,另一个细节是直接用到了赋值语句”c =getchar()”的返回值,把它和EOF进行比较 while((c = getchar()) != EOF)
  • 每输入一个字符,都可以直接输出一个字符,因此getchar是输入的理想方法
  • isalpha来判断字符是否为字母,类似的还有idigit、isprint等,在ctype.h中定义。if(isalpha(ch)) return rev[ch - ‘A’];
  • 如果在执行函数的过程中碰到了return语句,将直接退出这个函数,不去执行后面的语句。相反,如果在执行过程中始终没有return语句,则会返回一个不确定的值。幸好,-Wall可以捕捉到这一可疑情况并产生警告。
  • C语言用调用栈来描述函数之间的调用关系。调用栈由栈帧(Stack Frame)组成,每一个栈帧对应在一个未运行完的函数。
  • 以数组为参数调用函数时,实际上只有数组首地址传给了函数,需要另外加一个参数表示元素个数。除了把数组首地址本身作为实参外,还可以利用指针加减法把其他元素的首地址传递给函数。
  • 在可执行文件中,正文段(Text Segment)用于存储指令,数据段(Data Segment)用于存储医初始化的全局变量,BSS段(BSS Segment)用于存储未赋值的全局变量所需要的空间。调用栈并不储存在可执行文件中,而是在运行时创建。调用栈所在的段称为堆栈段(Stack Segment)
  • 运行时,程序会动态创建一个堆栈段,里面存放着调用栈,因此保存着函数的调用关系和局部变量。
  • static关键字当它用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的链接属性,从external改为internal,但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问
  • static关键字当它用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,并在程序的整个执行期间一直存在,而不是每次在代码块开始执行时创建,在代码块执行完毕后销毁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值