C语言技术积累
2016-09-08 16:08
204 查看
1. 如何十六进制打印一个char型数据
#include <stdio.h>
int main(int argc, char **argv)
{
char c = 0x80;
printf("%02x\n", (unsigned
char)c);
return 0;
}
如果不要红色加粗部分。结果是在当c小于0x80的时候是正确的,
因为%x格式化的类型是int或unsigned int, 所以c会被提升为int,
当c大于等于0x80时会被当作负数处理,为保留符号位,因此提升时
c会变为0xffffff80, 显然不正确。
2.C/C++中如何获取数组的长度?
C、C++中没有提供 直接获取数组长度的函数,对于存放字符串的字符数组提供了一个strlen函数获取长度,那么对于其他类型的数组如何获取他们的长度呢?其中一种方法是使 用sizeof(array) / sizeof(array[0]), 在C语言中习惯上在 使用时都把它定义成一个宏,比如#define GET_ARRAY_LEN(array,len)
{len = (sizeof(array) / sizeof(array[0]));} 。而在C++中则可以使用模板 技术定义一个函数,比如:
template <class T>
int getArrayLen(T& array)
{
return (sizeof(array) / sizeof(array[0]));
}
例如:
int main()
{
char a[] = {'1','2','3','4'};
int len;
GET_ARRAY_LEN(a,len)
//调用预定义的宏,取得数组a的长度,并将其存储在变量len中
printf("%d\n",len);
system("pause");
return 0;
}
3.用数组名做函数参数
可以用数组名作函数参数,此时实参与形参都应用数组名(或指针变量)。
例2:有一个一维数组score,内放10个学生成绩,求平均成绩。
float average(float array[10]){
int i;
float aver,sum=array[0];
for(i=1; i<10; i++)sum=sum+array[i];
aver=sum/10;
return aver;
}
main(){
float score[10],aver;
int i;
printf("input 10 scores:/n");
for(i=0; i<10; i++)scanf("%f",&score[i]);
printf("/n");
aver=average(score);//数组名作为函数参数
printf("average score is %5.2f",aver);
}
说明:
l 用数组名称作函数参数,应该在主调函数和被调函数分别定义数组,本例中array是形参数组名,score是实参数组名,分别在其所在的函数中定义,不能只在一方定义。
l 实参数组与形参数组类型应该保持一致(这里都为float型),如不一致,结果将出错。
l 在被调用函数中声明了形参数组的大小为10,但在实际上,指定其大小是不起任何作用的,因为C编译器对形参数组大小不做检查,只是检查实参数组的首地址传给形参数组。因此,score
和array
指的是同一单元。
l 形参数组也可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,有时为了在被调用函数中处理数组元素的需要,可以另设一个参数,传递需要处理的数组元素的个数,上例可以改写为下面的形式:
float average(float array[], int n){
int i;
float aver,sum=array[0];
for(i=1; i<n; i++)sum=sum+array[i];
aver=sum/n;
return aver;
}
main(){
float score_1[5]={98.5,97,91.5,60,55};
float score_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99,5};
printf("the average of class A is %6.2f/n", average(score_1, 5));
printf("the average of class B is %6.2f/n", average(score_2, 10));
}
最后应该说明一点:用数组名作为函数实参的时,不是吧数组元素的值传递给形参,而是把实参数组的起始地址传递给形参数组。
形参数组中各个元素的值如果发生变化会使实参数组元素的值同时发生变化,从上图是很容易理解的。这一点与变量做函数参数的情况是不同的,务必注意!在程序设计中可以有意识地利用这一点。
4.总结一下C语言定义数组的几种形式:
以一维数组为例
int arr[10];
int arr[] = {1,2,4};
int arr[10] = {1,2};
int *arr = new int[10];
前面三种常常都可以用到,但使用第四种时需要注意。在.c文件里使用这种形式编译会不能通过, 但.cpp文件里是可以的,可以推断出这是C++对C的扩展。
上面的结论完全来自于Visual Studio环境下的实践,对于tc,bdc,gcc等情况下是否成立有待考证。
bug最多的还是程序端没有被执行,一般使用Debug调试,但是有的时候成百上千次的循环中不适合断点调试,所以使用串口打印,最常用的错误定位方法是:
#define MARK(s) printf("%s,%d,%s\r\n",__FILE__,__LINE__,s)
使用就是例如MARK("tangquan");,打印出来就是main.c,115,tangquan
事实上除非出现很麻烦的问题一般我不用debug,串口大部分问题都能搞定的。
#include <stdio.h>
int main(int argc, char **argv)
{
char c = 0x80;
printf("%02x\n", (unsigned
char)c);
return 0;
}
如果不要红色加粗部分。结果是在当c小于0x80的时候是正确的,
因为%x格式化的类型是int或unsigned int, 所以c会被提升为int,
当c大于等于0x80时会被当作负数处理,为保留符号位,因此提升时
c会变为0xffffff80, 显然不正确。
2.C/C++中如何获取数组的长度?
C、C++中没有提供 直接获取数组长度的函数,对于存放字符串的字符数组提供了一个strlen函数获取长度,那么对于其他类型的数组如何获取他们的长度呢?其中一种方法是使 用sizeof(array) / sizeof(array[0]), 在C语言中习惯上在 使用时都把它定义成一个宏,比如#define GET_ARRAY_LEN(array,len)
{len = (sizeof(array) / sizeof(array[0]));} 。而在C++中则可以使用模板 技术定义一个函数,比如:
template <class T>
int getArrayLen(T& array)
{
return (sizeof(array) / sizeof(array[0]));
}
例如:
int main()
{
char a[] = {'1','2','3','4'};
int len;
GET_ARRAY_LEN(a,len)
//调用预定义的宏,取得数组a的长度,并将其存储在变量len中
printf("%d\n",len);
system("pause");
return 0;
}
3.用数组名做函数参数
可以用数组名作函数参数,此时实参与形参都应用数组名(或指针变量)。
例2:有一个一维数组score,内放10个学生成绩,求平均成绩。
float average(float array[10]){
int i;
float aver,sum=array[0];
for(i=1; i<10; i++)sum=sum+array[i];
aver=sum/10;
return aver;
}
main(){
float score[10],aver;
int i;
printf("input 10 scores:/n");
for(i=0; i<10; i++)scanf("%f",&score[i]);
printf("/n");
aver=average(score);//数组名作为函数参数
printf("average score is %5.2f",aver);
}
说明:
l 用数组名称作函数参数,应该在主调函数和被调函数分别定义数组,本例中array是形参数组名,score是实参数组名,分别在其所在的函数中定义,不能只在一方定义。
l 实参数组与形参数组类型应该保持一致(这里都为float型),如不一致,结果将出错。
l 在被调用函数中声明了形参数组的大小为10,但在实际上,指定其大小是不起任何作用的,因为C编译器对形参数组大小不做检查,只是检查实参数组的首地址传给形参数组。因此,score
和array
指的是同一单元。
l 形参数组也可以不指定大小,在定义数组时在数组名后面跟一个空的方括号,有时为了在被调用函数中处理数组元素的需要,可以另设一个参数,传递需要处理的数组元素的个数,上例可以改写为下面的形式:
float average(float array[], int n){
int i;
float aver,sum=array[0];
for(i=1; i<n; i++)sum=sum+array[i];
aver=sum/n;
return aver;
}
main(){
float score_1[5]={98.5,97,91.5,60,55};
float score_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99,5};
printf("the average of class A is %6.2f/n", average(score_1, 5));
printf("the average of class B is %6.2f/n", average(score_2, 10));
}
最后应该说明一点:用数组名作为函数实参的时,不是吧数组元素的值传递给形参,而是把实参数组的起始地址传递给形参数组。
形参数组中各个元素的值如果发生变化会使实参数组元素的值同时发生变化,从上图是很容易理解的。这一点与变量做函数参数的情况是不同的,务必注意!在程序设计中可以有意识地利用这一点。
4.总结一下C语言定义数组的几种形式:
以一维数组为例
int arr[10];
int arr[] = {1,2,4};
int arr[10] = {1,2};
int *arr = new int[10];
前面三种常常都可以用到,但使用第四种时需要注意。在.c文件里使用这种形式编译会不能通过, 但.cpp文件里是可以的,可以推断出这是C++对C的扩展。
上面的结论完全来自于Visual Studio环境下的实践,对于tc,bdc,gcc等情况下是否成立有待考证。
bug最多的还是程序端没有被执行,一般使用Debug调试,但是有的时候成百上千次的循环中不适合断点调试,所以使用串口打印,最常用的错误定位方法是:
#define MARK(s) printf("%s,%d,%s\r\n",__FILE__,__LINE__,s)
使用就是例如MARK("tangquan");,打印出来就是main.c,115,tangquan
事实上除非出现很麻烦的问题一般我不用debug,串口大部分问题都能搞定的。
相关文章推荐
- python 编程语言基础技术框架
- 在工作中积累,做好自己的技术(转载)
- IT职场人生系列之十五:语言与技术II
- 秋色园QBlog技术原理解析:独创的多语言翻译机制(九)
- 软件开发技术逐步积累汇总
- IT职场人生系列之十二:语言与技术I
- ASP.NET 2.0 本地化技术之研究 (多语言的实现)
- JRuby语言内部报道:重要的软件开发混合(Hybrid)技术Swiby
- swift语言之多线程操作和操作队列(下)———坚持51天吃掉大象(写技术文章)
- 【程序员技术练级】学习一门脚本语言 python(三)跟数据库打交道
- 简易机顶盒launcher开发技术积累
- 笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-03 联接查询
- 多语言网站开发 不完全技术分析收录
- 零基础如何掌握Java技术体系语言特…
- D语言中的内存管理技术
- 软件技术积累-问题引出之一
- 技术积累应用-可视化编程平台概述
- 想带几个徒弟,C#.NET开发技术方面的,把自己积累的软件技术传授给高徒[非网络带人]
- 2016最全面的编程语言技术开发视频+源码+技巧+软件+面试全汇总