C和指针笔记(二)

时间:2022-09-09 20:01:27

@本文纯属个人笔记,如有错误还请多加指出!

源程序的预处理,编译,汇编和链接

我目前的知识水平只知道预处理时会处理#include,将其需要包含的内容包含进来,处理#define,替换符号常量。
编译就是通过词法、语法等分析产生汇编代码,汇编是指将汇编指令转换为对应的机器代码,之后链接就是链接一些必须要的库。

三字母词

C中使用三个字母表示一个符号可能会引起一些意想不到的输出,比如??(代表[

字符串

当使用字符串时,便宜器会给字符串分配空间,并返回一个地址。
字符数组只能在初始化的时候使用字符串,字符串不能给字符数组赋值。

    char array[]="abc";//正确
    array="abc";//错误

字符串存在于表达式时,其值为这些字符的存储地址,而不是字符本身,所以不能赋值给字符数组。但是可以赋值给一个指向字符的指针。这个指针指向字符串的存储地址。

    char *str="ab";//正确
    str="abc";//正确

注意,数组名和指针是有区别的,参考:
数组名和指针的区别

typedef

在定义指针变量时,比如:
char* a,b,c;其实只有a是指针变量,b和c都是字符变量。
我们可以用typedef为数据类型定义新的名字,比如:

    typedef char *pChar;
    pChar a,b;

这样定义的a和b都为指针变量。
而且typedef#define是不一样的,前者是为数据类型定义新的名字,而后者只是简单的文本替换。

常量

可以用关键字const来定义常量,常量不可以被赋值,因为其值为不可变的。const常量获得值有两种方法,第一种就是在定义的时候初始化,这之后就不能修改了。第二种是const常量作为函数的形参,当函数调用时,const常量参数获得实参的值。
当面对指针时,根据const修饰的位置不一样,所限制的常量也不一样:

    int const *p;//值不可变,但地址可变
    int * const p;//值可变,但地址不可变

举例代码:

    //公用
    int num1=1;
    int num2=2;
    int const *p1=&num1;
    *p1=3;//错误,值不可变
    p1=&num2;//正确,地址可变

    int * const p2=&num1;
    *p2=3;//正确,值可变
    p2=&num2;//错误,地址不可变

还需要主要的是,const声明的常量只能用在变量可以使用的地方,即使它的值不能被改变。所以,const声明的常量不能用于定义数组的大小(但是,这是ANSI的规定,用GCC等可以编译,但是会有警告)(经过尝试,现在没有警告了)。

运算符结合顺序

操作符 描述 结合性
!,~,++, - - 前缀自增自减 R-L
*,& 间接访问和取地址 R-L
(类型) 类型转换 R-L
sizeof 取长度 R-L
= 赋值 R-L
+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|= R-L

记住一些结合顺序还是很有必要的,如果一旦万一遇到类似这样的代码++*++p也不至于完全不知道。
++(前缀)*都是R-L结合的,所以这条语句实际上是取p指针后面一个内存单元存储的值,然后自增。