c笔记09---字符数组及字符串,预处理,宏,条件编译

来源:互联网 发布:vip后缀域名无法备案 编辑:程序博客网 时间:2024/05/03 18:29
1.    C语言中,使用第一个字符的地址,表示整个字符串。'\0' 是字符串的结尾字符,他的位置决定了一个字符串中有效字符变量的个数。
    '\0' 在 ASCII 中对应数字 0 ;

2.    字面值是程序中表示字符串的一种写法,用双引号表示,不可以被修改。
    多个相同内容的字面值在程序运行时都是同一个地址。
    多个连续的字符串在编译时会被合并成一个。
    char *p = "abc";                // p 表示字符串首地址,该值不能被修改
    char *p1 = 'a';                    // 错误,提示整数类型不可以赋值给指针,传递的是 a 对应的 ASCII 值;
    // 如果是 char *p1 = "a"; 则正确;传递的是 a 在内存中的地址;
    printf("%s\n", p);
    *p = 'm';                        // 错误,字符串字面值不可以修改
    printf("%p\n", "abc");            // 此处打印出来的地址和上面 p 打印出来的地址一样
    printf("%s\n", "abc""xyz");        // 输出为一个字符串:abcxyz;

    字符数组也可以表示字符串,它存储在栈中。可以被修改,可以使用多种方式初始化。
    char str[] = "abc";
    char str1[3] = "abc";                // 这个写法不对,因为 '\0' 没处放;
    char str2[] = {'a', 'b', 'c'};        // 错误,没有 0 ,不可以当数组用
    char str3[] = {'a', 'b', 'c', 0};    // 正确
    printf("%s\n", str);                // 输出为:abc
    printf("%d\n", sizeof(str) / sizeof(str[0]));
    // 计算出字符串数组大小,输出为:4。因为后面还有一个 '\0',在编译的时候计算机自动加上。
    str[0] = 'm';                        // 数组表示的字符串可以改动,和上面的字面值不一样
    str[1] = 0;
    printf("%s\n", str);                // 输出为:m,因为第二个为 0,所以计算机自动停止

3.    字符串数组常用操作:(denglu.c)
    首先,字符串数组要包含头文件: #include <string.h>
    fgets 函数用来从键盘读取字符串,不会出现字符数组溢出问题;
    strlen 计算字符串长度(实际长度);
    strcat 合并两个字符串,第二个参数的首字符必须为 char 类型;
            此函数容易导致合并后长度过长,溢出。
        strncat 合并字符串,且避免溢出。
    strcpy 赋值字符串,同样容易溢出。
        strncpy 赋值字符串,且避免溢出。
    strcmp 通过 ASCII 比较字符串大小。前者大,返回 1;后者大返回 -1;一样大返回 0。
        strncmp 比较两字符串中前 n 个字符大小。

    #include <string.h>
    char buf[10] = {0};
    fgets(buf, 10, stdin);            // 若输入字符超过9个,只提取前面9个,最后留一个0位置。若少于9个,那么会把\n读进去。
    printf("%d\n", strlen(buf));    // 计算字符串有效字符长度(不包括 “\0”)
    char str[10] = "abc";
    strcat(str, "x0yz");            // str = str + "x0yz";
    strcpy(str, "wqq");                // str = "wqq";
    strcmp("abc","acd");            // 返回 -1
    
    char arr[10];
    printf ("%d\n", sizeof (arr));    // 10
    printf ("%d\n", strlen (arr));    // 9

4.    main函数参数(了解即可,很少使用)
    int main(int argc, char *argv[])

5.    预处理命令 #define 专门给数字取名字,如给 3.14 取名字:
    #define PI 3.14f                  // 后面不可以加分号,也不可以加赋值等号。
    用#define取的名字叫宏,如此处 PI 即为宏;名字之间不能有空格,即不能写为:P I;
    
    另外一种宏定义方式:
    在gcc(终端)里面输入:gcc -D PI=3014 code.c

6.    宏不仅可以定义数字,还可以定义公式等,即带参数宏:
    #define PI  3.14f
    #define CIRCLE(r)  2 * PI * (r)        // 一般给参数加个(),保证参数先运算
    #define SQRE    (60 * 60)            // 若是个计算式,记得加个括号
    #define SQUARE(n)        ((n) * (n))
    #define STR(n)    #n                    // 把参数字符串化,相当于 “n”,如:STR(6+3),输出结果为:6+3
    #define PTR(n)    p_##n                // 重命名标志符,如:PTR(value),输出结果为:p_value
    宏的参数既是输入参数,又是输出参数;且参数要用()。
    不要使用自增或自减作为参数传递给宏。

    编译器预定义的一些宏:
    printf("%d\n", __LINE__);    // 显示当前行号
    printf("%s\n", __FILE__);    // 当前文件名
    printf("%s\n", __DATE__);    // 当前编译日期
    printf("%s\n", __TIME__);    // 当前编译时间
    printf("%s\n", __STDC__ ? "符合" : "不符合");    // 查看编译器是否符合C标准,如果符合打印“符合”,反之“不符合”;
    
    问:论述含参数的宏与函数的优缺点 ?
    答:        带参宏                函数
    ---------------------------
    处理时间    编译时                程序运行时
    参数类型    没有参数类型问题    定义实参、形参类型
    处理过程    不分配内存            分配内存
    程序长度    变长                不变
    运行速度    不占运行时间        调用和返回占用时间

7.    条件编译:
    #ifdef 宏名称  // 或者(#ifndef 宏名称)
        ***
    #else
        ***
    #endif

    举例如下:
    #define ONE
    int main()
    {
        #ifdef ONE            // 如果定义了ONE宏,则运行下面语句,打印one,否则运行else,打印two
            printf("one");
        #else
            printf("two");
        #endif
        retrun 0;
    }

    类似形式如下:
    #define ONE
    int main()
    {
        #ifndef ONE            // 如果没定义ONE,打印one,否则打印two。
            printf("one");
        #else
            printf("two");
        #endif
        retrun 0;
    }

8.    条件编译:
    #if 条件表达式    // 这样的条件编译范围变大,#ifdef 相当于 #if defined(宏名称) ,此条件表达式末尾没有符号
        ***
    #else
        ***
    #endif

    多条件编译:
    #if 条件表达式
        ***
    #elif    条件表达式
        ***
        ***
    #else
        ***
    #endif    

0 0