C语言使用相关汇总(一)

1、sizeof操作符

sizeof(类型说明符,数组名或表达式)

sizeof 变量名

作用:返回一个对象或类型所占的内存字节数

size是尺寸,of是……的。比如sizeof(int)就是int型在内存中的尺寸,也就是大小了。

2、memset和memcpy

memset表达式:memset(a,0,sizeof(a))

memset解释:将a中前sizeof(a)个字节用0替换并返回a。

memset作用:在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20);

memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

例子详见Zigbee学习/第三章基础实验/9.串口通讯-发送字符串:

void main(void)
{
    CLKCONCMD &= ~0x40;               //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);          //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;               //设置系统主时钟频率为32MHZ
     
    InitUart();                       //设置串口相关寄存器
    memset(TxData, 0, TX_SIZE);       //数据清0
    memcpy(TxData, TX_STRING, sizeof(TX_STRING)); //复制发送字符串到TxData
       
    while(1)
    {
        UartSendString(TxData, sizeof(TX_STRING)); //串口发送数据
        DelayMS(1000);                 //延时
    }
}

3、srand()与rand()函数

高级语言中带的随机数产生函数是伪随机数,伪随机数的意思是并不是真正意义上的随机数,而是通过某种运算或者在某种程度上产生随机的效果。由于计算机是一种图灵机,相同的输入必定产生相同的输出。所以,我们必须在C语言随机数的基础上加上某种比较随机的条件,简称种子。这样产生的随机数才会看起来比较随机,而不会每次运行程序的时候是一样的了。比如光用rand,产生5个随机数,每次运行程序可能结果都是一样的可能都是4 9 3 8 7 但是使用了当前系统时间为种子的话,每次运行结果就可能不一样了 假设第一次运行是5 1 0 3 9 第二次运行可能就是8 7 1 3 4

srand 初始化随机种子,rand 产生随机数。

rand函数

头文件: 

定义函数:int rand(void)

函数功能:产生随机数

函数说明:因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期特别长,所以,在一定的范围里可看成是随机的。rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。

返回值: 返回0至RAND_MAX之间的随机整数值,RAND_MAX的范围最少是在32767之间(int),即双字节(16位数)。若用unsigned int 双字节是65535,四字节是4294967295的整数范围。且0-RAND_MAX每个数字被选中的机率是相同的。

rand()产生的是假随机数字,每次执行时是相同的。若要不同,以不同的值来初始化它.初始化的函数就是srand()。

函数举例:

#include“stdlib.h”
#include “stdio.h”
int main(void)
{
  int i,j;
  for(i=0; i<10; i++)
  {
    j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    printf("%d ",j);
  }
  printf("\n");
  return 0;
}

第一次运行结果:  (每次运行结果都相同)

   

第二次运行结果:

 

srand函数

头文件:  “stdlib.h”//修改为<>

定义函数:void srand (unsigned int seed);

函数说明:srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用getpid()或time(0)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。

函数举例:

#include “stdlib.h”
#include “stdio.h”
#include “time.h”
int main(void)
{
  int i,j;
  srand((int)time(NULL));
  for(i=0; i<10; i++)
  {
    j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    printf("%d ",j);
  }
  printf("\n");
  return 0;
}

第一次运行结果:(每次运行结果都不同)

第二次运行结果:

例子:

求做一个模拟产生学生成绩的程序,成绩要求在四十到一百分之间,保留一位小数,而且小数位要是零或五
程序的一部分是这样的
while((n=400+rand()601)%5);
score[i]=n/10.0;
printf("%5.1d",score[i]");

rand() 能产生0-RAND_MAX之间的随机数,rand() % 601生成一个 0-600的数,则 n 从400-1000。
在后面的计算成绩处,把 score =n / 10, 即 n的个位,变成SCORE的小数部分;
又要求 小数 为0 或5, 所以 n 的个位必须是0或5,即能被5整除,n % 5 == 0;
如果 n 不能被5整除,即 n%5 > 0;
while((n=400+rand()601)%5);作用是产生一个400-1000的数,如果不能被5整除,则另产生一个数,直到该数能被5整除。
PS:rand()601 产生的数并不是随机的。如RAND_MAX = 700, 并假定产生RAND能产生0-700间的随机数,那么 rand()601后,原来0-600的数还是0-600,601-700的数变成 0-99,所以0-99 的机率要比其它数大一倍。

4、continue与break
1. break可用于switch语句,表示跳出整个switch块,而continue则不能用于switch语句
2. 它们都可用于循环语句的循环体,所谓的区别也应该是它们对循环次数的影响不同。break用于立即退出当前循环,而continue仅跳过当次循环(本次循环体内不执行continue语句后的其它语句,但下次循环还会执行)。举例说明。
int i;
int s = 0;
for (int i = 1; i <= 10; i++)
{
  if (i == 6) break;
  s += i;
}
上面的循环会因为break语句而在i=6时提前终止,这样s的最终值就是1+2+3+4+5
如将break换成continue
int i;
int s = 0;
for (int i = 1; i <= 10; i++)
{
  if (i == 6) continue;
  s += i;
}
当i=6时就不会将i累加到s中,s的最终值是1+2+3+4+5+7+8+9+10,唯独少一个6

5、++i和i++的区别

在游戏中就i++ 我加你 ++i是求人家加。区别在于 应答与请求
在编程中i++和++i最终是一样的,不过在循环体中,i++是先取出i,再加1,++i先加后取

6、Sizeof与Strlen的区别与联系

1).sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
2).sizeof是算符,strlen是函数。
3).sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。
sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
4).数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5).大部分编译程序在编译的时候就把sizeof计算过了是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6).strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
7).sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
8).当适用了于一个结构类型时或变量, sizeof 返回实际的大小,
当适用一静态地空间数组, sizeof 归还全部数组的尺寸。
sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
9).数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8])
fun(char [])
都等价于 fun(char *)
在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小
如果想在函数内知道数组的大小, 需要这样做:
进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
  unsigned char* buf = new unsigned char[len+1]
  memcpy(buf, p1, len);
}
我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度
看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:
char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
上面是对静态数组处理的结果,如果是对指针,结果就不一样了
char* ss = "0123456789";
sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是长整型的,所以是4
sizeof(*ss) 结果 1 ===》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间,是char类型的,占了 1 位

strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen。

7、指针

float (*p)(float)是什么意思

声明了一个指针p,p指向一个具有一个float类型形参的函数,这个函数返回一个float型值。
或者说是:声明了一个指向具有一个float类型形参、返回类型为float的函数的指针P。
本人认为后一种说法正规些,但很绕口;第一种好理解,但略欠规范。

8、! 与~的区别

! 这个是 逻辑反,凡是a的值不为0的,!a  就等于0; 如果a的值为0,则 !a 的值为1;

~这个是按位取反。

比如:

int a=2 ; 用二进制表示为00 00 00 10; 则!a = 0;

 ~a = 11 11 11 01 (按位取反后的二进制结果,此结果为补码形式)

求其源码为 :10 00 00 11  即为-3,所以~a 的结果为-3。

9、sprintf字符串格式化命令

函数原型:int sprintf( char *buffer, const char *format [, argument] … );

主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数,最常见的应用之一莫过于把整数打印到字符串中。

1) 十进制打印:

//把整数123 打印成一个字符串保存在s 中。

sprintf(s, "%d", 123); //产生"123"

可以指定宽度,不足的左边补空格:

sprintf(s, "MM", 123, 4567); //产生:" 1234567"

当然也可以左对齐:

sprintf(s, "%-4dM", 123, 4567); //产生:"123 4567"

2) 16 进制打印:

sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐

sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐

这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。

sprintf(s, "X", 4567); //产生:"000011D7"

上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。

3) 注意一个符号扩展的问题

比如,假如我们想打印短整数(short)-1 的内存16 进制表示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:

short si = -1;

sprintf(s, "X", si);

产生“FFFFFFFF”,怎么回事?因为sprintf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就把32 位整数-1 的8 位16 进制都打印出来了。

如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不是补符号位):

sprintf(s, "X", (unsigned short)si);

就可以了。或者:

unsigned short si = -1;

sprintf(s, "X", si);

sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和16 进制都不会打印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。

4) 控制浮点数打印格式

浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保留小数点后6 位数字,比如:

sprintf(s, "%f", 3.1415926); //产生"3.141593"

但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表示打印的宽度,n 表示小数点后的位数。比如:

sprintf(s, ".3f", 3.1415626); //产生:" 3.142"

sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "

sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"

注意一个问题,你猜

int i = 100;

sprintf(s, "%.2f", i);

会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:

sprintf(s, "%.2f", (double)i);

5) 实际应用

(1) 该函数包含在stdio.h的头文件中。

#include "stdio.h"

(2) sprintf与printf函数的区别

sprintf和平时我们常用的printf函数的功能很相似。

sprintf函数打印到字符串中。

printf函数打印输出到屏幕上。

sprintf函数在我们完成其他数据类型转换成字符串类型的操作中应用广泛。

(3) sprintf函数的格式:
int sprintf( char *buffer, const char *format [, argument,...] );
除了前两个参数固定外,可选参数可以是任意个。buffer是字符数组名;format是格式化字符串(像:"=%6.2f%#x%o",%与#合用时,自动在十六进制数前面加上0x)。只要在printf中可以使用的格式化字符串,在sprintf都可以使用。其中的格式化字符串是此函数的精华。

(4) 可以控制精度

char str[20];
double f=14.309948;
sprintf(str,"%6.2f",f);
(5) 可以将多个数值数据连接起来。

char str[20];

int a=20984,b=48090;
sprintf(str,"=m",a,b);
str[]="20984 48090"
(6) 可以将多个字符串连接成字符串

char str[20];
char s1={'A','B','C'};
char s2={'T','Y','x'};
sprintf(str,"%.3s%.3s",s1,s2);

%m.n在字符串的输出中,m表示宽度,字符串共占的列数;n表示实际的字符数。%m.n在浮点数中,m也表示宽度;n表示小数的位数。

(7) 可以动态指定,需要截取的字符数
char s1={'A','B','C'};
char s2={'T','Y','x'};
sprintf(str,"%.*s%.*s",2,s1,3,s2);
sprintf(s, "%*.*f", 10, 2, 3.1415926); 

(8) 可以打印出i的地址sprintf(s, "%p", &i);

上面的语句相当于
sprintf(s, "%0*x", 2 * sizeof(void *), &i);

(9) sprintf的返回值是字符数组中字符的个数,即字符串的长度,不用在调用strlen(s)求字符串的长度。

(10) VC++测试

#include "stdio.h"

int main(void) 

  char s[40];

  sprintf(s,"%s%d%c","test",1,'2'); //把结果输出到指定的字符串中

  printf("%s\n",s);

}

10、printf格式化字符串

Turbo C2.0提供的格式化规定符如下:

符号 作用

%d 十进制有符号整数

%u 十进制无符号整数

%f 浮点数

%s 字符串

%c 单个字符

%p 指针的值

%e 指数形式的浮点数

%x, %X 无符号以十六进制表示的整数

%0 无符号以八进制表示的整数

%g 自动选择合适的表示法

说明:

(1). 可以在"%"和字母之间插进数字表示最大场宽。

例如: = 表示输出3位整型数, 不够3位右对齐。

%9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。

%8s 表示输出8个字符的字符串, 不够8个字符右对齐。如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出。但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出。

另外, 若想在输出值前加一些0, 就应在场宽项前加个0。

例如: d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。

如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。

例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。

(2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。

例如: %ld 表示输出long整数

      %lf 表示输出double浮点数

(3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。

例如: %-7d 表示输出7位整数左对齐

      %-10s 表示输出10个字符左对齐

2. 一些特殊规定字符

字符 作用

\n 换行

\f 清屏并换页

\r 回车

\t Tab符

讨论:例如串口接收单片机发送的16进制的数据,则我们要这样接收:

byte buf[56];

recv(comm->handle,buf);

buf[strlen(buf)]=0;//打上结束标志

//将接收的数字转化为16进制串

char *pstr=new char[256];

byte *pb=&buf[0];

while(!pb) 

sprintf(pstr++,"x",*pb++);

11、原码、反码、补码的理解

1)讨论原码之前首先需要了解两个概念:机器数和真值。

a.一个数值在计算机中的二进制表示形式,就称为这个数值的机器数。机器数是带符号的,其中最高位是符号位,1表示负数,0表示正数。比如,

1100 0000就是-64的机器数,即在计算机中的二进制表示形式。同样的,0100 0000就是64的机器数。

b.真值:因为第一位是符号位,所以机器数的形式值并不是真正的数值。机器数中除符号位之外的二进制串表示的才是真值(当然要加上符号才是真正的值)。

2)对于一个数,在计算机中如何表示呢?这就涉及到对其的编码问题,原码、反码、补码就是计算机中对数的三种编码方式。

a.原码就类似于上述机器数的定义方式,一个数的原码就是符号位加上真值的绝对值,即第一位表示符号位,其余位表示值。

-64的原码就是:1100 0000

+64的原码就是:0100 0000

计算机中只有加法器没有减法器,减法运算是转化为加法来进行的。以下举例说明使用原码进行加减法的过程:

64+64=0100 0000 + 0100 0000=0 1000 0000=128

64-64=64+(-64)=0100 0000+ 1100 0000=1 0000 0000=-0

1-1=1+(-1)=0000 0001 + 1000 0001=1000 0010=-2  计算错误

原码的表示方式存在的问题:

1.存在+0、-0的情况(0000 1000)

2.进行减法运算的时候,有些情况会计算出错(1-1=-2)

b.为了解决减法运算会出错的情况,引入了反码的编码形式。对于正数,其反码与原码完全相同(原码表示下,加法是正确的,所以正数的反码保持与原码相同即可),而负数的反码是保持原码的符号位不变,所有位依次取反,就得到反码。以下分别给出+1,-1的反码形式,并使用反码进行减法运算:

+1=[0000 0001]

-1=[1111 1110]

1-1=1+(-1)=0000 0001+1111 1110=1111 1111,结果是反码形式,需要将其转化为原码形式才能得到确切值,原码是1000 0000=-0。

但是反码对于0的表示方法任然是有两种,这里以4 bit为例:

0000 +0

1111 -0

c.采用了反码的形式之后,减法运算的结果是正确了的。不过对于0还是存在+0、-0的情况。为了解决这个问题,补码出现了。正数的补码就是其原码自身,负数的补码是在其反码的基础上+1。还是以+1、-1的补码形式说明:

+1=0000 0001

-1=1111 1111

1-1=1+(-1)=1 0000 0000 丢掉最高位=0000 0000=0(正数的补码和原码相同,所以是0)。

使用补码不仅解决了+0、-0的情况,而且还可以多表示一个最低数。下图以4 bit为例,说明了原码、反码、补码的”进化过程“:

以下讨论原码和补码两种编码形式下,表示的取值范围。从上图易知,分别使用原码和补码,4 bits的取值范围是:

原码:[-7,7](包含+0、-0)

补码:[-8,7](只有一个0)

两种编码方式都表示了16个数值,只是原码有+0、-0之分,而补码只有一个0(+0),没有-0,因此可多表示一个最小值-8。-8的补码推倒过程如下:

-1-7=1111+1001=1000=-8,所以-8的补码是1000,其没有对应的反码和原码。

而8 bits的范围是:

补码:[-128,127] 1000 0000=-128

因此对于n bits分别以原码、补表示的数值取值范围是:

原码:[-(2^(n-1)-1),2^(n-1)-1]   有1个符号位,所以是n-1

补码:[-(2^(n-1)),2^(n-1)-1]

3)计算机中是以补码的形式表示数值的(起码是整数),编程语言也是以补码的形式表示数值的。

根据负数的原码求补码有一个比较简单的计算方法:符号位保持不变。从最低位开始,直至遇到第一个1之前,之前的所有位保持不变。遇到第一个1之后,保留这个1,以后按位取反直到符号位后一位。

根据负数的补码求其原码的方法:符号位保持不变,其余各位取反,然后再整个数加1。

另外,两个二进制数相减,等于加上减数保持符号位不变,取反 +1,即使加上其补码。

4)计算机只有加法器,将减法转化成加法,是利用了数学中的同余概念。

11、十六进制与BCD码相互转换

十六进制转为BCD码好理解,有问题的是BCD码转为十六进制数;
Hex2Bcd:
0x3F的BCD码是多少?正确答案:99,或者0x63
0x3F=63,再加0x,->0x63, 再把0x63转为99(0x63=99)
1、如果要表示为十六进制,则转换为10进制数,前面加0x符号;(十六进制表示)
2、如果要表示为十进制,则先转换为10进制数,前面加0x符号,再把加上符号的。
十六进制数转为十进制数;(十进制表示) 如果一个数为0x38,则BCD码为86。

Bcd2Hex:(注:)
1、如果这个数是16进制表示的,把0x符号去掉,当成10进制数直接转换为16进制数即可;
(前提是这个16进制表示的数的任何一位不能大于9,也就是说不能出现A、B、C、D、E、F)
如:0x999,去掉0x,->999,再转为十六进制数为0x3E7
2、如果这个数是十进制表示的,先把这个数转换为16进制数,再把0x符号去掉,当成
十进制数,再转化为十六进制数即可;(注:这个数要在一定范围内,才行,如999转换为
十六进制为0x3E7,把0x去掉,3E7不在10进制表示范围内,)

上面说的是在一定范围内的数,对于不在一定范围内的数怎么转?刚开始还真不好理解,是因为学校教给我们的数学规则限制了我们的思维,对于一个数3E7,当成10进制怎么理解?还是按十进制来,个位、十位、百位...,只不过现在十位上的数是14,

BCD码999转换为十六进制是多少?正确答案:447,若者0x1BF,为什么?想不通...
转换过程:
999转为十六进制,->0x3E7,
3
3*10+E=44
(3*10+E)*10+7
=447   也就相当于0x3E7当成10进制理解,则是3*100+E*10+7,简单不?

注:一个十六进制数转为BCD码,但这个BCD码再转为十六进制数,不等于这个数;
如:如果一个数为0x999,Hex2Bcd(0x999)=0x2547(9543),Bcd2Hex(0x2547)=0x9F3(2547),而一个BCD码的数可以转为十六进制数,这个十六进制数可以反转为BCD码,可能等于这个数(这个数是十六进制表示,且每一位的数字在0~9之间);也可能不等于这个数。
如:Bcd2Hex(0x999)=0x3E7(999),Hex2Bcd(0x3E7)=2457(0x999)(等于)
   Bcd2Hex(0x9F3)=0x41D(1053),Hex2Bcd(0x41D)=0x1053(4179)
   Bcd2Hex(999)=0x1BF(447),Hex2Bcd(0x1BF)=0x447(1095)(不等于)
   Bcd2Hex(0x447)=0x1BF(447),Hex2Bcd(0x1BF)=0x447(1095)(等于)

结论:16进制转BCD不可逆,BCD转16进制有可能可逆。

  1. unsigned char BCD2HEX(unsigned char bcd_data)    //BCD转为HEX子程序
  2. {   
  3.     unsigned char temp;
  4.     temp=(bcd_data/16*10 + bcd_data);   
  5.     return temp;   
  6. }   
  7. unsigned char HEX2BCD(unsigned char hex_data)    //HEX转为BCD子程序
  8. {   
  9.     unsigned char temp;   
  10.     temp=(hex_data/10*16 + hex_data);   
  11.     return temp;   
  12. }

12、浮点数与整数比较大小

C语言中浮点数不能直接和整数比较大小,一般方法如下。

1)首先将整数转换为浮点数可以用牵制类型转换或赋值给double变量;其次两浮点数相减最后差值取绝对值,检查差值与要求精度差距。

#include "math.h"

int equ_double_int(double a, int c)
{
    if(fabs(a-c) < 0.00005) 

        return(1);   

    else

        return(0);   
}

2)将整数乘以1.0,比如int a; a*1.0编译器认为就是一个浮点数。

3)类型强制转换。

4)float x=10.001;int a=10;

      if(floor(x+0.0005)>a)

13、数组

1)定义一个空数组

输出3,6,9,12......

#include"stdio.h"

void main()

{

    int array[100];//空数组的定义

    int i;

    //循环赋值

    for(i=0; i<100; i++)

        array[i] = (i + 1) * 3;

    //输出

    for(i=0; i<100; i+=)

        printf("array[%d] = %d\n", i, array[i]);

}

2)不定长数组(realloc见“C语言使用相关汇总二”第13

(1)手里有一小段MATLAB程序需要转化成C语言。
MATLAB里输入的矩阵可以是任意大小的,但是C语言里的数组一定要是固定大小,对于大小不能确定的数组我想到了用malloc动态申请内存,但是就算用malloc也必须是申请一大小的存储空间(比如键盘输入的).....
但是我的matlab里的向量的长度是根据以前的数据算出来的,在MATLAB里非常容易得到向量长度,一句length(a)就知道向量长度了,MATLAB里不知道长度的向量怎样转化成C语言里的数组并且可以求得其元素个数

假设数组存的是int型那么你先申请10个元素
int* a = (int*)malloc(sizeof(int)*10);
如果又来了个元素,那么你就可以
a=(int *)realloc(a,11*sizeof(int)); //更改已经配置的内存空间动态分配地址然后不够再追加
求元素个数int i,n=1;
for(i = 0;(a+i)!=NULL;i++)
  ;
n=i+1;//n就是元素个数

如果你定义的是int型数组比如 int a[10];的长度就更简单了,n = sizeof(a)/sizeof(int)

(2)用指针,如:
long *UserTime = (long *)malloc(size);//size是你动态需要的大小
然后就可以:
memset(UserTime,0,size);//初始化为0
UserTime[0] = xxx;//象数组那样使用
UserTime++;//等于数组下标加一
UserTime += xxx;//等于下标加xxx
用完:
free(UserTime);//释放

(3)C++程序

#include "stdio.h"
#include "malloc.h"
int main()
{
    printf("输入数组大小:\n");
    int size;
    scanf("%d",&size);
    int i;
    char *array = (char*)malloc(size * sizeof(int));
    for(i=0;i
    {
        printf("请输入数组元素!\n");
        scanf("%d",&array[i]);
        printf("array[%d]=%d\n",i,array[i]);
    }
    free(array);//malloc申请的内存free来释放,new申请的内存用delete释放
    return 0;
}

C语言使用相关汇总二

永不止步步 发表于12-22 14:42 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67410个|学分:345327个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号