【编程总结】关于C语言的一些小细节

1.C语言不能够使用基本赋值运算符 “=”为数组赋值,即 b=a;这样的赋值是错误的。如果要赋值,可以用for语句为数组的元素逐一赋值

2.赋值运算符“=”具有右结合性, min = max = fenshu[0],需要理解成 min = (max = fenshu[0])

3.字符常量的类型是int类型,除此之外,还存在显示字符的 char 类型

void put_chars(int ch , int n)
{
    while(n-->0)
        putchar(ch);
}

put_chars(' ', 5) //输出5个空格,空格是作为int类型参数传入函数的

4.为函数传递数组参数时,只要在调用该函数时,使用的实参写数组的名称即可,不需要加"[]"


int max_of(int v[],int n);
//接收数组的形参声明为“类型名 参数名[]”,使用n来接收元素个数

int eng[NUMBER];
int mat[NUMBER];
max_e = max_of(eng,NUMBER); //eng为数组名,不需要加[]
max_m = max_of(mat,NUMBER); //mat为数组名,不需要加[]

5.在自定义函数的形参中加上const类型修饰符,可以进制在函数内部修改传入的参数的值(例如禁止修改接收到的数组内容)

void print_array(const int v[],int n);
//本函数只能够打印数组元素,无法修改数组元素的值,如果修改,编译器会报错

6.创建多维数组/函数接收多维数组。数组元素个数可以不规定,但是元素的类型必须固定

void func1(int v[], int n); // 元素类型为int,元素个数随意(n)
void func2(int v[][3], int n); // 元素类型为int[3],元素个数随意(n)
void func3(int v[][2][3], int n); // 元素类型为int[2][3],元素个数随意(n)
//函数接收的数组的元素类型必须固定,元素个数是自由的

7.元素类型为int型的数组,称为int数组;元素类型为int类型,个数为n的数组,写作 int[n]型,数组类型为int[n]

8.printf函数中%u转换说明表示unsigned型的无符号整型数值,%d以十进制数的形式显示,%o以八进制显示,%x%X以十六进制显示

9.按位运算符,&、^、|、~的操作数必须整数类数据类型或者是枚举型,不可应用于浮点型等数据类型的操作数

10.位移运算符<<、>>的操作数必须是整数类数据类型或者枚举型

11.浮点型数 x 经过循环累加0.01到1.0后,最后的x的值是0.999999而不是1.0,这是因为计算机不能够保证其内部转换为二进制的浮点数的每一位都不发生数据丢失,因此将1000份的误差积累在 x 中(明解C语言P225)

12.union联合体的长度问题

union的长度取决于其中的长度最大的那个成员变量的长度。即union中成员变量是重叠摆放的,其开始地址相同。

其实union(共用体)的各个成员是以同一个地址开始存放的,每一个时刻只可以存储一个成员,这样就要求它在分配内存单元时候要满足两点:   
  1.一般而言,共用体类型实际占用存储空间为其最长的成员所占的存储空间;   
  2.若是该最长的存储空间对其他成员的元类型(如果是数组,取其类型的数据长度,例int  a[5]为4)不满足 
    整除关系,该最大空间自动延伸;   
  
  我们来看看这段代码:   

  union   mm{   
  char   a;//元长度1   
  int   b[5];//元长度4   
  double   c;//元长度8   
  int   d[3]; //元长度4
  };   
   本来mm的空间应该是sizeof(int)*5=20;但是如果只是20个单元的话,那可以存几个double型(8位)呢?两个半?当然不可以,所以mm的空间延伸为既要大于20,又要满足其他成员所需空间的整数倍,,因为含有double元长度8,故大小为24。
所以union的存储空间先看它的成员中哪个占的空间最大,拿他与其他成员的元长度比较,如果可以整除就行。

13.为绝对地址的数据赋值

//设置一绝对地址为 0x67a9 的整型变量的值为 0xaa66
//方法一(推荐):
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;

//方法二
*(int * const)(0x67a9) = 0xaa55;

14.让程序跳转到绝对地址是 0x100000 去执行

*((void(*)( ))0x100000 ) ( ); 

/***
首先要将 0x100000 强制转换成函数指针,
即: (void(*)())0x100000 然后再调用它:*((void (*)())0x100000)(); 

用 typedef
可以看得更直观些: 
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();

**/

 15.typedef定义函数指针

typedef char (*PTRFUN)(int); 
PTRFUN pFun; 
char glFun(int a){ return;} 
void main() 
{ 
    pFun = glFun; 
    (*pFun)(2); 
} 

tpyedef定义了一个新类型,定义了一个PTRFUN类型,这个类型是指向某个函数的指针,这个函数的返回值为char类型,参数为int类型。这里的typedef用法和普通的增加别名用法不一样,具体可以参考https://baurine.github.io/2013/03/18/understand_typdef_funp.html

第二行的代码便使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。

参考:

16.typedef struct和指针

typedef struct student
{
    int age;
    int height;
    char name[5];
    struct student *pNext;
}STUDENT, *PSTUDENT;

STUDENT为struct student的别名

PSTUDENT为struct student* 的别名,是一个结构体指针的别名

等价于

struct student
{
    int age;
    int height;
    char name[5];
    struct student *pNext;
}

typedef struct student STUDENT;

typedef struct student *PSTUDENT;

STUDENT *xuesheng等价于 PSTUDENT xuesheng

参考资料:https://blog.csdn.net/u013814701/article/details/52996544

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值