0、前言:
- 宏定义传参可以理解成一种更便捷的函数,但和函数有明显区别的一点就是宏定义传参主打一个替换,其次就是实现简单逻辑可以,复杂的就不行了。
- volatile关键字和extern关键字是干什么的要知道即可
- 字符串数组很重要,特别是定义方式很重要,还有就是常用的字符串函数要知道其作用,传入的参数,是否有返回值。特别是传入的参数和返回值类型,很重要,不像python记个差不多就行,在c中函数使用非常严谨。
1、宏定义传参:
- 1.1、单条语句举例:#define len(arr) sizeof(arr)/sizeof(arr[0]) // 宏定义传参单条语句
- 1.2、多条语句举例:#define swap(a,b,type) { type temp;temp = a;a = b;b = temp;} // 宏定义传参多条语句(★)
2、两个了解即可的关键字:
- volatile关键字避免寄存器优化,导致结果不一致,这个和常量修改有关系,比如在C++中通过指针地址强制修改常量的值会触发寄存器优化,导致指向常量的指针值可以改变,但常量的值被优化保存了下来。
- extern关键字用于声明外部"变量"或"函数",表明该变量或函数的定义在其他文件(或当前文件的其他位置),告诉编译器 “这个标识符在别处已经定义过了,这里只是引用它”。如果是其他文件定义的静态变量(static),那么则不能通过这种方式引用。一般而言,最好是通过头文件管理外部变量声明。
3、字符串数组(C语言中的字符串):
- 定义:在 C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。因此,\0 是用于标记字符串的结束。
- 补充:在C语言中NULL 是一个 指针,用于表示指针不指向任何有效地址。不能用NULL代替\0,因为\0是一个字符,为什么用\0作为字符串结束符呢?因为用0结束会误认为是字符0,因此加个转移符号\作为结束符。
- ★字符数组初始化时长度超过定义长度会报错,长度小于定义长度,后面会全部补\0,用一整个字符串给字符数组初始化时,不写长度,它会自动补\0,如果是逐个字符初始化要记得最后加\0,否则不识别字符串结束位置。
- \0作为字符串结束符是很重要的一个知识,有时候设置字符串数组大小的时候,忽略这个问题就会出错,下面用代码来演示一些只可意会的东西:
#include<stdio.h>
#include<stdlib.h>
int main() {char a1[] = { 'a','b','c' };char a11[] = { 'a','b','c' ,'\0'};printf("a11:%s", a11); char a[100] = ""; char a2[4] = { 'a','b','c','\0' }; char a3[5] = { 'a','b','c'}; char a4[] = "abc"; char a5[3] = "abc";char * a6 = "abc"; char* a7 = (char*)malloc(4 * sizeof(char));int i;if (a7 != NULL) {for (i = 0; i < 3; i++) {a7[i] = a6[i];}a7[i] = '\0';printf("a7:%s\n", a7); free(a7); }char a8[5] = "abc"; char const* a9 = "abc";char* a10[3] = { a1,a2,a3 };printf("a1:%s\n", a1); printf("a2:%s\n", a2); printf("a3:%s\n", a3); printf("a4:%s\n", a4); printf("a5:%s\n", a5); printf("a6:%s\n", a6); printf("a8:%s\n", a8); printf("a9:%s\n", a9); for (i = 0; i < 3; i++) {printf("i:%d,%s\n",i, a10[i]);}return 0;
}
4、字符串函数:
- 要在C语言中使用字符串数组,就要在预处理命令中引入string.h头文件;在visual studio中还有还有一个很有帮助的功能,就是写出来这种头文件中引用的函数之后,如果忘记函数参数,可以鼠标悬停在该函数上面查看函数的形参。
- 内存操作函数:以mem开头的函数
char a[5] = "abcd";
char b[3] = "ef";
memset(a, 'm', 2);
printf("a:%s", a);
printf("\n-----------\n");memcpy(a, b, 1);
printf("a:%s", a);
printf("\n-----------\n");
printf("strlen(ad b ):%zu", strlen("ad b "));
printf("\n-----------\n");strcpy(a, b);
printf("a:%s", a);
printf("\n-----------\n");strncpy(a,"abc",3);
printf("a:%s", a);
printf("\n-----------\n");char c[10] = "ab";
strcat(c, a);
printf("c:%s", c);
printf("\n-----------\n");strncat(c, "mm",1);
printf("c:%s", c);
printf("\n-----------\n");printf("%d", strcmp("aBc", "AbC"));
printf("\n-----------\n");printf("c字符串的开始位置:%p,找到'b'的位置:%p", c, strchr(c, 'b'));
printf("\n-----------\n");printf("c字符串的开始位置:%p,找到最后一个'b'的位置:%p", c, strrchr(c, 'b'));
printf("\n-----------\n");
printf("c字符串的开始位置:%p,找到最后一个“efgca”中任一字符第一次出现的位置:%s", c, strpbrk(c, "efgcb"));
printf("\n-----------\n");printf("c字符串%s中bcd在第%zu位", c,(strstr(c, "bcd") - c));
printf("\n-----------\n");
char d[30] = "a,b,c d e";
printf("d:%s\n", d);
char* p1 = strtok(d, ", ");
while (p1) {printf("p1:%s\n",p1);p1 = strtok(NULL, ", ");
}
printf("\n-----------\n");
char e[5] = "A2,aB";
printf("%d\n", isalpha(e[0]));
printf("%d\n", isdigit(e[1]));
printf("%d\n", isalnum(e[2]));
printf("%d\n", isupper(e[3]));
printf("%d\n", islower(e[3]));
总结:
- 宏定义传参可以理解为一种基于替换方法简单逻辑的函数。
- 字符串数组的重点内容就是怎么样初始化一个字符串数组。
- 字符串函数的重点就是详细掌握这些函数当中的参数。