标签:
strstr的while dowhile模型 |
//int cltClient_rev(void *handle, unsigned char *buf, int *buflen) //不要相信别人给你传送的内存地址是可用的 int getCout(char *str, char *substr, int *count) { int rv = 0; char *p = str;
int ncout = 0; if (str==NULL || substr== NULL || count==NULL) { rv = -1; printf("func getCout()check (str==NULL || substr== NULL || count==NULL) err:%d \n" , rv); return rv; }
do { p = strstr(p, substr); if (p == NULL) //没有找到则跳出来 { break; } else { ncout++; p = p + strlen(substr); }
} while (*p != ‘\0‘);
//fuzhi *count = ncout;
printf("ncout:%d\n", ncout); return rv;
} |
void main36() { char *p = "abcd1111abcd222abcd3333"; int ncout = 0;
while (p = strstr(p, "abcd")) { p = p + strlen("abcd"); ncout ++; if (*p == ‘\0‘) { break; } } printf("ncout:%d\n", ncout); system("pause"); } |
两头堵模型(两种写法) |
//求去掉空格 //int trimSpaceStr2(char *p, unsigned char *buf2, int *buf2len) int trimSpaceStr2( char *p, char *buf2) { int ret = 0;
int ncount = 0; int i, j; i = 0; j = strlen(p) -1;
while (isspace(p[i]) && p[i] != ‘\0‘) { i++; }
while (isspace(p[j]) && j>0 ) { j--; }
ncount = j - i + 1; // strncpy(buf2, p+i, ncount); buf2[ncount] = ‘\0‘; return ret; }
//求去掉空格 //int trimSpaceStr2(char *p, unsigned char *buf2, int *buf2len) //不要轻易去改变指针输入特性中in内存块的内存。。。。 int trimSpaceStr2_notgood( char *p) { int ret = 0;
int ncount = 0; int i, j; i = 0; j = strlen(p) -1;
while (isspace(p[i]) && p[i] != ‘\0‘) { i++; }
while (isspace(p[j]) && j>0 ) { j--; }
ncount = j - i + 1; // strncpy(p, p+i, ncount); p[ncount] = ‘\0‘; return ret; } |
字符串反转模型 |
void main51() { char p[] = "abcde"; char c ; char *p1 = p; char *p2 = p + strlen(p) -1;
while (p1 < p2) { c = *p1; *p1 = *p2; *p2 = c; ++p1; --p2; }
printf("p:%s \n", p); system("pause");
} |
|
int getKeybyValue(char *pKeyValude, char *pKey, char *pValude) { char rv = 0; char *p = NULL;
if (pKeyValude==NULL ) { rv = -1; printf("func getKeybyValue() err:%d pKeyValude \n", rv); return rv; } if ( pKey==NULL ) { rv = -1; printf("func getKeybyValue() err:%d pKey=NULL \n", rv); return rv; } if ( pValude==NULL ) { rv = -1; printf("func getKeybyValue() err:%d pValude \n", rv); return rv; }
//1 在pKeyValude中查找是否有关键字pKey p = strstr(pKeyValude, pKey); if (p == NULL) { rv = -1; printf("func getKeybyValue() err:%d 查找没有关键字pKey \n", rv); return rv; } p = p + strlen(pKey); //为下一次检索做准备
//2 有没有= p = strstr(p, "="); if (p == NULL) { rv = -2; printf("func getKeybyValue() err:%d 查找没有= \n", rv); return rv; } p = p + 1; //为下一次提取valude做准备
//3 提取按照要求的valude rv = trimSpaceStr03(p, pValude); if (rv != 0) { printf("func trimSpaceStr03() err:%d \n", rv); return rv; }
return rv; } |
测试字符串常量和字符数组 类型的变量地址是否相同。
实现此案例需要按照如下步骤进行。
步骤一:字符串地址的测试
代码如下所示:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char *str = "This is a string.";
- char array[100];
- strcpy(array, str);
- printf("字符串常量的地址:%p\n", str);
- printf("字符数组的地址:%p\n", array);
- return 0;
- }
上述代码中,以下代码:
- char *str = "This is a string.";
定义了一个字符型指针str,用于指向一个字符串常量。
上述代码中,以下代码:
- printf("字符串常量的地址:%p\n", str);
- printf("字符数组的地址:%p\n", array);
使用printf函数分别输出字符串常量的地址和字符数组的地址。从输出结果可见,它们是不相同的。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char *str = "This is a string.";
- char array[100];
- strcpy(array, str);
- printf("字符串常量的地址:%p\n", str);
- printf("字符数组的地址:%p\n", array);
- return 0;
- }
定义一个int类型的指针,指向一个整型变量,然后分别使用&和*取得地址或者数据。
实现此案例需要按照如下步骤进行。
步骤一:字符串的定义和使用
代码如下所示:
- #include <stdio.h>
- int main()
- {
- char str[5] = {};
- scanf("%4s", str);
- printf("%s\n", str);
- return 0;
- }
上述代码中,以下代码:
- char str[5] = {};
定义了一个字符数组str,该数组有5个元素。
上述代码中,以下代码:
- scanf("%4s", str);
使用scanf函数输入一个字符串。其中,%4s是限定输入的字符串中字符的个数不能大于4,否则将只输入前4个字符。指定值为4是因为字符数组str的长度为5,多出来的一个需要存储\0。
上述代码中,以下代码:
- printf("%s\n", str);
使用函数printf输出字符串。字符数组所对应的格式控制符是%s。
本案例的完整代码如下所示:
- #include <stdio.h>
- int main()
- {
- char str[5] = {};
- scanf("%4s", str);
- printf("%s\n", str);
- return 0;
- }
使用指针实现字符串的函数strlen()、strcat()的功能,可以自定义两个函数。
实现此案例需要按照如下步骤进行。
步骤一:字符串函数的使用
代码如下所示:
- #include <stdio.h>
- int mystrlen(char *str)
- {
- int count = 0;
- while (*str)
- {
- count++;
- str++;
- }
- return count;
- }
- char* mystrcat(char *s, char *d)
- {
- char* old = s;
- while(*s)
- s++;
- while(*d)
- {
- *s = *d;
- s++;
- d++;
- }
- return old;
- }
- int main()
- {
- char str[100] = "This is ";
- printf("str的长度为:%d\n", mystrlen(str));
- char* str1 = "a string";
- mystrcat(str, str1);
- printf("连接后的字符串为:%s\n", str);
- return 0;
- }
上述代码中,以下代码:
- int mystrlen(char *str)
- {
- int count = 0;
- while (*str)
- {
- count++;
- str++;
- }
- return count;
- }
定义了一个函数mystrlen,用于模拟库函数strlen的功能。该函数的参数为求长度的字符串。在该函数中,以下语句:
- int count = 0;
首先定义一个整型变量count,用于存储字符串中字符的个数。在该函数中,以下语句:
- while (*str)
- {
- count++;
- str++;
- }
设置一个循环,逐个计算字符串中字符的个数,当*str不为\0时,代表该字符串没有结束。在该函数中,以下语句:
- return count;
返回字符串的长度。
上述代码中,以下代码:
- char* mystrcat(char *s, char *d)
- {
- char* old = s;
- while(*s)
- s++;
- while(*d)
- {
- *s = *d;
- s++;
- d++;
- }
- return old;
- }
定义了一个函数mystrcat,用于模拟库函数strcat的功能。该函数的两个参数为将字符串d连接到字符串s的后面。在该函数中,以下语句:
- char* old = s;
首先保存被连接字符串的首地址,用于函数结束返回时作返回值用。在该函数中,以下语句:
- while(*s)
- s++;
设置一个循环找到被连接字符串的结束符\0,以便将另一个字符串连接到这个位置。在该函数中,以下语句:
- while(*d)
- {
- *s = *d;
- s++;
- d++;
- }
设置一个循环将字符串d的每一个字符拷贝到字符串s的结束字符\0开始的空间中,实现连接功能。在该函数中,以下语句:
- return old;
返回字符串s的首字符地址。
注意:由于上述循环中,指针s已经发生了变化,所以不能直接返回。
上述代码中,以下代码:
- int main()
- {
- char str[100] = "This is ";
- printf("str的长度为:%d\n", mystrlen(str));
首先,在主函数中定义一个字符数组,用于存储字符串"This is "。
然后,调用自定义函数mystrlen求得字符数组的长度,并输出。
上述代码中,以下代码:
- char* str1 = "a string";
- mystrcat(str, str1);
- printf("连接后的字符串为:%s\n", str);
首先,在主函数中定义一个字符指针,用于指向字符串"a string"。
然后,调用自定义函数mystrcat将字符指针指向的字符串拼接到字符数组str中,并输出。
最后,输出连接后的字符数组str。
本案例的完整代码如下所示:
- #include <stdio.h>
- int mystrlen(char *str)
- {
- int count = 0;
- while (*str)
- {
- count++;
- str++;
- }
- return count;
- }
- char* mystrcat(char *s, char *d)
- {
- char* old = s;
- while(*s)
- s++;
- while(*d)
- {
- *s = *d;
- s++;
- d++;
- }
- return old;
- }
- int main()
- {
- char str[100] = "This is ";
- printf("str的长度为:%d\n", mystrlen(str));
- char* str1 = "a string";
- mystrcat(str, str1);
- printf("连接后的字符串为:%s\n", str);
- return 0;
- }
使用指针函数实现文件名和文件目录的拼接。
实现此案例需要按照如下步骤进行。
步骤一:字符串函数的使用(续1)
代码如下所示:
- #include <stdio.h>
- char* filenamecat(char *path, char* name)
- {
- char* old = path;
- while(*path)
- path++;
- if (*(path - 1) != ‘/‘)
- {
- *path = ‘/‘;
- path++;
- }
- while(*name)
- {
- *path = *name;
- path++;
- name++;
- }
- return path;
- }
- int main()
- {
- char path[100] = "/home/tarena/";
- char* filename = "字符串函数的使用.c";
- filenamecat(path, filename);
- printf("带路径的文件名为:%s\n", path);
- return 0;
- }
上述代码中,下面代码行:
- char* filenamecat(char *path, char* name)
- {
- char* old = path;
- while(*path)
- path++;
- if (*(path - 1) != ‘/‘)
- {
- *path = ‘/‘;
- path++;
- }
- while(*name)
- {
- *path = *name;
- path++;
- name++;
- }
- return old;
- }
定义了一个函数filenamecat,用于拼接文件路径和文件名的功能。该函数的两个参数为将文件名字符串name连接到路径字符串path的后面。在该函数中,以下语句:
- char* old = path;
首先保存路径字符串的首地址,用于函数结束返回时作返回值用。在该函数中,以下语句:
- while(*path)
- path++;
设置一个循环找到路径字符串的结束符\0,以便将文件名字符串连接到这个位置。在该函数中,以下语句:
- if (*(path - 1) != ‘/‘)
- {
- *path = ‘/‘;
- path++;
- }
判断路径字符串的最后一个字符是否是/,如果不是则首先在路径字符串的最后添加字符/。在该函数中,以下语句:
- while(*name)
- {
- *path = *name;
- path++;
- name++;
- }
设置一个循环将文件名字符串name的每一个字符拷贝到路径字符串path的结束字符/后面的空间中,实现连接功能。在该函数中,以下语句:
- return old;
返回路径字符串path的首字符地址。
注意:由于上述循环中,指针path已经发生了变化,所以不能直接返回path。
上述代码中,下面代码行:
- int main()
- {
- char path[100] = "/home/tarena/";
- char* filename = "字符串函数的使用.c";
首先,定义一个数组path,用于保存路径名。
然后,定义一个指针filename,用于指向文件名。
上述代码中,下面代码行:
- filenamecat(path, filename);
调用自定义函数filenamecat,将文件名filename连接到路径名path的后面。
上述代码中,下面代码行:
- printf("带路径的文件名为:%s\n", path);
使用函数printf输出连接后的路径加文件名。
本案例的完整代码如下所示:
- #include <stdio.h>
- char* filenamecat(char *path, char* name)
- {
- char* old = path;
- while(*path)
- path++;
- if (*(path - 1) != ‘/‘)
- {
- *path = ‘/‘;
- path++;
- }
- while(*name)
- {
- *path = *name;
- path++;
- name++;
- }
- return path;
- }
- int main()
- {
- char path[100] = "/home/tarena/";
- char* filename = "字符串函数的使用.c";
- filenamecat(path, filename);
- printf("带路径的文件名为:%s\n", path);
- return 0;
- }
测试不同类型的指针的算术运算。
实现此案例需要按照如下步骤进行。
步骤一:字符串的基本操作
代码如下所示:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char str[100];
- strcpy(str, "tarena");
- printf("字符串为:%s\n", str);
- if (strcmp(str, "tarena"))
- printf("字符串str与tarena不同\n");
- else
- printf("字符串str与tarena相同\n");
- printf("sizeof(str) = %ld\n", sizeof(str));
- printf("strlen(str) = %lu\n", strlen(str));
- strcat(str, " C++方向");
- printf("字符串拼接后为:%s\n", str);
- printf("字符串拆分的前一部分为:%s\n", strtok(str, " "));
- printf("字符串拆分的后一部分为:%s\n", strtok(NULL, " "));
- char* p = strstr(str, "re");
- if (p)
- printf("子串re在字符串tarena中的位置为:%ld\n", p - str);
- else
- printf("子串re不在字符串tarena中\n");
- strcpy(str, "a 10 13.5");
- int i;
- double d;
- char c;
- sscanf(str, "%c%d%lf\n", &c, &i, &d);
- printf("%c %d %lf\n", c, i, d);
- memset(str, 0, sizeof(str));
- sprintf(str, "%c %d %lf\n", c, i, d);
- printf("%s\n", str);
- return 0;
- }
上述代码中,以下代码:
- char str[100];
- strcpy(str, "tarena");
- printf("字符串为:%s\n", str);
使用strcpy函数,将字符串"tarena"赋值到字符数组str中。
上述代码中,以下代码:
- if (strcmp(str, "tarena"))
- printf("字符串str与tarena不同\n");
- else
- printf("字符串str与tarena相同\n");
使用函数strcmp,逐个对比字符串"tarena"与字符数组str中的对应字符。如果所有对应字符均相同则返回0,否则返回非0值。
上述代码中,以下代码:
- printf("sizeof(str) = %ld\n", sizeof(str));
- printf("strlen(str) = %lu\n", strlen(str));
使用函数printf分别打印sizeof(str)和strlen(str)的值。从运行结果可以看出是不相同的。sizeof(str)输出的是字符数组str中所有元素所占的字节数。strlen(str)输出的是字符数组str中保存的字符串长度。
上述代码中,以下代码:
- strcat(str, " C++方向");
- printf("字符串拼接后为:%s\n", str);
使用函数strcat在字符串str的最后一个字符的后面连接上字符串" C++方向"。
上述代码中,以下代码:
- printf("字符串拆分的前一部分为:%s\n", strtok(str, " "));
- printf("字符串拆分的后一部分为:%s\n", strtok(NULL, " "));
使用函数strtok将刚拼接好的字符串str重新拆分成"tarena"和" C++方向"。
上述代码中,以下代码:
- char* p = strstr(str, "re");
- if (p)
- printf("子串re在字符串tarena中的位置为:%ld\n", p - str);
- else
- printf("子串re不在字符串tarena中\n");
首先,使用函数strstr在字符串str中查找子串"re"是否存在,如果存在则返回子串"re"的第一个字符r在字符串str的中的地址。然后,使用函数printf输出字符r在字符串中的位置。如果不存在,则输出子串不在字符串中。
上述代码中,以下代码:
- strcpy(str, "a 10 13.5");
- int i;
- double d;
- char c;
- sscanf(str, "%c%d%lf\n", &c, &i, &d);
- printf("%c %d %lf\n", c, i, d);
使用函数sscanf将字符串"a 10 13.5"中的字符a,整数10,双精度浮点数13.5转换到字符变量c,整型变量i,双精度浮点型变量d中。
上述代码中,以下代码:
- memset(str, 0, sizeof(str));
- sprintf(str, "%c %d %lf\n", c, i, d);
- printf("%s\n", str);
首先,将字符数组str中的所有元素清0。
然后,使用sprintf将字符变量c,整型变量i,双精度浮点型变量d中的值转换成字符串,存储到数组str中。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- char str[100];
- strcpy(str, "tarena");
- printf("字符串为:%s\n", str);
- if (strcmp(str, "tarena"))
- printf("字符串str与tarena不同\n");
- else
- printf("字符串str与tarena相同\n");
- printf("sizeof(str) = %ld\n", sizeof(str));
- printf("strlen(str) = %lu\n", strlen(str));
- strcat(str, " C++方向");
- printf("字符串拼接后为:%s\n", str);
- printf("字符串拆分的前一部分为:%s\n", strtok(str, " "));
- printf("字符串拆分的后一部分为:%s\n", strtok(NULL, " "));
- char* p = strstr(str, "re");
- if (p)
- printf("子串re在字符串tarena中的位置为:%ld\n", p - str);
- else
- printf("子串re不在字符串tarena中\n");
- strcpy(str, "a 10 13.5");
- int i;
- double d;
- char c;
- sscanf(str, "%c%d%lf\n", &c, &i, &d);
- printf("%c %d %lf\n", c, i, d);
- memset(str, 0, sizeof(str));
- sprintf(str, "%c %d %lf\n", c, i, d);
- printf("%s\n", str);
- return 0;
- }
定义三国五虎上将名单的数组,然后输入人名,判断是否是五虎上将。
实现此案例需要按照如下步骤进行。
步骤一:定义五虎上将名单
使用字符指针数组作为名单。
代码如下:
- #include <stdio.h>
- int main(int argc, const char * argv[])
- {
- char *tiger[5] = {"GuanYu", "ZhangFei", "ZhaoYun", "MaChao", "HuangZhong"};
- return 0;
- }
步骤二:输入一个名字
定义一个字符数组,用于存储从控制台输入的名字。
代码如下:
- #include <stdio.h>
- int main(int argc, const char * argv[])
- {
- char *tiger[5] = {"GuanYu", "ZhangFei", "ZhaoYun", "MaChao", "HuangZhong"};
- char name[20];
- printf("请输入一个名字:");
- scanf("%s", name);
- return 0;
- }
步骤三:遍历数组
遍历数组,逐个将数组元素与输入的名字对比,查找是否为五虎上将之一。
- #include <stdio.h>
- #include <string.h>
- int main(int argc, const char * argv[])
- {
- char *tiger[5] = {"GuanYu", "ZhangFei", "ZhaoYun", "MaChao", "HuangZhong"};
- char name[20];
- printf("请输入一个名字:");
- scanf("%s", name);
- int i;
- for (i = 0; i < 5; i++)
- if (strcmp(name, tiger[i]) == 0)
- {
- printf("%s是五虎上将之一。\n", name);
- break;
- }
- if (i == 5)
- printf("%s不是五虎上将之一。\n", name);
- return 0;
- }
注意:strcmp函数需要包含string.h这个头函数。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include <string.h>
- int main(int argc, const char * argv[])
- {
- char *tiger[5] = {"GuanYu", "ZhangFei", "ZhaoYun", "MaChao", "HuangZhong"};
- char name[20];
- printf("请输入一个名字:");
- scanf("%s", name);
- int i;
- for (i = 0; i < 5; i++)
- if (strcmp(name, tiger[i]) == 0)
- {
- printf("%s是五虎上将之一。\n", name);
- break;
- }
- if (i == 5)
- printf("%s不是五虎上将之一。\n", name);
- return 0;
- }
测试#include的用法,包括gcc –I指定目录。
实现此案例需要按照如下步骤进行。
步骤一:#include指令的使用
代码如下所示:
- #include <stdio.h>
- #include "print.c"
- int main()
- {
- print();
- return 0;
- }
上述代码中,以下代码:
- #include "print.c"
使用#include 指令将文件print.c中的内容添加到本程序的文件中。
上述代码中,以下代码:
- int main()
- {
- print();
- return 0;
- }
在主程序中调用print.c中的函数print。
print.c代码如下所示:
- void print()
- {
- printf("调用在文件print.c中的print函数\n");
- }
上述代码中,以下代码:
- printf("调用在文件print.c中的print函数\n");
使用函数printf输出提示,该函数被调用了。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include "print.c"
- int main()
- {
- print();
- return 0;
- }
print.c代码如下所示:
- void print()
- {
- printf("调用在文件print.c中的print函数\n");
- }
测试宏变量的基本用法
实现此案例需要按照如下步骤进行。
步骤一:宏变量的使用
代码如下所示:
- #include <stdio.h>
- #define SIZE 10
- #define BEGIN int main() {
- #define END return 0; }
- #define LOOP for (int i = 0; i < SIZE; i++)
- BEGIN
- int array[SIZE];
- printf("请输入10个整数(空格分隔):");
- LOOP scanf("%d", &array[i]);
- LOOP printf("array[%d] = %d\n", i, array[i]);
- END
上述代码中,以下代码:
- #define SIZE 10
定义一个宏变量SIZE,用于定义数组元素的个数。
上述代码中,以下代码:
- #define BEGIN int main() {
定义一个宏变量BEGIN,用于代替后面的主函数定义。
上述代码中,以下代码:
- #define END return 0; }
定义一个宏变量END,用于代替后面的主函数返回。
上述代码中,以下代码:
- #define LOOP for (int i = 0; i < SIZE; i++)
定义一个宏变量LOOP,用于代替设置一个循环。
上述代码中,以下代码:
- BEGIN
在预编译阶段,会被替代为以下语句:
- int main() {
上述代码中,以下代码:
- LOOP scanf("%d", &array[i]);
在预编译阶段,会被替代为以下语句:
- for (int i = 0; i < SIZE; i++) scanf("%d", &array[i]);
上述代码中,以下代码:
- LOOP printf("array[%d] = %d\n", i, array[i]);
在预编译阶段,会被替代为以下语句:
- for (int i = 0; i < SIZE; i++) printf("array[%d] = %d\n", i, array[i]);
上述代码中,以下代码:
- END
在预编译阶段,会被替代为以下语句:
- return 0; }
本案例的完整代码如下所示:
- #include <stdio.h>
- #define SIZE 10
- #define BEGIN int main() {
- #define END return 0; }
- #define LOOP for (int i = 0; i < SIZE; i++)
- BEGIN
- int array[SIZE];
- printf("请输入10个整数(空格分隔):");
- LOOP scanf("%d", &array[i]);
- LOOP printf("array[%d] = %d\n", i, array[i]);
- END
写一个宏函数,用它来验证一个日期是否合法。
实现此案例需要按照如下步骤进行。
步骤一:宏函数的定义
- #define IS_DATE_VALID(year, month, day) \
- if ((year) > 2000 && (year) < 2020 && (month) > 0 && (month) < 13 && (day) > 0 && (day) < 32)\
- printf("日期合法\n");\
- else\
- printf("日期不合法\n");
- int main()
- {
- IS_DATE_VALID(2015,3,15);
- return 0;
- }
上述代码中,以下代码:
- #define IS_DATE_VALID(year, month, day) \
- if ((year) > 2000 && (year) < 2020 && (month) > 0 && (month) < 13 && (day) > 0 && (day) < 32)\
- printf("日期合法\n");\
- else\
- printf("日期不合法\n");
定义了一个宏函数IS_DATE_VALID,用于测试一个日期是否合法。上述代码中,\ 代表换行,当宏函数中的字符串比较长时,可以用它来作为换行符,不能用回车,因为回车代表宏函数定义结束。
上述代码中,以下代码:
- IS_DATE_VALID(2015,3,15);
在预编译阶段,会被替代为以下语句:
- if ((year) > 2000 && (year) < 2020 && (month) > 0 && (month) < 13 && (day) > 0 && (day) < 32)\
- printf("日期合法\n");\
- else\
- printf("日期不合法\n");
本案例的完整代码如下所示:
- #define IS_DATE_VALID(year, month, day) \
- if ((year) > 2000 && (year) < 2020 && (month) > 0 && (month) < 13 && (day) > 0 && (day) < 32)\
- printf("日期合法\n");\
- else\
- printf("日期不合法\n");
- int main()
- {
- IS_DATE_VALID(2015,3,15);
- return 0;
- }
写一个头文件,使用条件编译实现避免重复include。
实现此案例需要按照如下步骤进行。
步骤一:条件编译的使用
main.c代码如下所示:
- #include <stdio.h>
- #include "print.h"
- int main()
- {
- print();
- return 0;
- }
上述代码中,以下代码:
- #include "print.h"
使用#include 指令将文件print.h中的内容添加到本程序的文件中。
print.h文件,代码如下所示:
- #ifndef print_h
- #define print_h
- void print();
- #endif
上述代码中,以下代码:
- #ifndef print_h
使用条件编译指令判断宏名print_h是否已经定义,如果没有定义继续执行下面的语句,否则直接跳到#endif后面的语句执行。
上述代码中,以下代码:
- #define print_h
如果没有定义宏名print_h,则执行此语句定义该宏名,这样下一次再使用#ifndef判断宏名print_h是否已经定义时,由于已经定义将跳过#endif之间的语句,防止重复include。
print.c文件,代码如下所示:
- #include <stdio.h>
- #include "print.h"
- void print()
- {
- printf("避免重复include例题\n");
- }
上述代码中,以下代码:
- #include "print.h"
在main.c函数中已经有此语句,如果没有条件编译语句会多次包含print.h文件。
本案例的完整代码如下所示:
main.c代码如下所示:
- #include <stdio.h>
- #include "print.h"
- int main()
- {
- print();
- return 0;
- }
print.h文件,代码如下所示:
- #ifndef print_h
- #define print_h
- void print();
- #endif
print.c文件,代码如下所示:
- #include <stdio.h>
- #include "print.h"
- void print()
- {
- printf("避免重复include例题\n");
- }
写一组头文件,然后按照条件选择一个进行编译。
要求:实现避免重复导入并且测试static的作用。
实现此案例需要按照如下步骤进行。
步骤一:short文件
short.h文件,代码如下所示:
- #ifndef short_h
- #define short_h
- short add(short a, short b);
- short sub(short a, short b);
- #endif
上述代码中,以下代码:
- #ifndef short_h
- #define short_h
- #endif
为防止重复include而预设的条件编译指令。
上述代码中,以下代码:
- short add(short a, short b);
- short sub(short a, short b);
声明短整型的加法add、减法sub运算函数。
short.c文件,代码如下所示:
- #include "short.h"
- short add(short a, short b)
- {
- return a + b;
- }
- short sub(short a, short b)
- {
- return a - b;
- }
上述代码中,以下代码:
- short add(short a, short b)
- {
- return a + b;
- }
短整型的加法add函数的定义。
上述代码中,以下代码:
- short sub(short a, short b)
- {
- return a - b;
- }
短整型的减法sub函数的定义。
步骤二:standard文件
standard.h文件,代码如下所示:
- #ifndef int_h
- #define int_h
- int add(int a, int b);
- int sub(int a, int b);
- #endif
上述代码中,以下代码:
- int add(int a, int b);
- int sub(int a, int b);
声明整型的加法add、减法sub运算函数。
standard.c文件,代码如下所示:
- #include "standard.h"
- int add(int a, int b)
- {
- return a + b;
- }
- int sub(int a, int b)
- {
- return a - b;
- }
整型的加法add、减法sub运算函数的定义。
步骤三:long文件
long.h文件,代码如下所示:
- #ifndef long_h
- #define long_h
- long add(long a, long b);
- long sub(long a, long b);
- #endif
上述代码中,以下代码:
- long add(long a, long b);
- long sub(long a, long b);
声明长整型的加法add、减法sub运算函数。
long.c文件,代码如下所示:
- #include "long.h"
- long add(long a, long b)
- {
- return a + b;
- }
- long sub(long a, long b)
- {
- return a - b;
- }
长整型的加法add、减法sub运算函数的定义。
步骤四:static文件
static.h文件,代码如下所示:
- #ifndef int_h
- #define int_h
- static void print();
- void call();
- #endif
上述代码中,以下代码:
- static void print();
声明了一个静态函数。该函数只能在本文件内部使用,在其他的.c文件中无法使用。
上述代码中,以下代码:
- void call();
定义了一个普通函数。
static.c文件,代码如下所示:
- #include <stdio.h>
- #include "static.h"
- static int ex = 10;
- void print()
- {
- printf("这是静态函数,只能在本文件中使用\n");
- }
- void call()
- {
- print();
- printf("静态变量:%d\n", ex);
- }
上述代码中,以下代码:
- static int ex = 10;
定义了一个静态变量ex,该变量只能在本文件内部使用,在其他的.c文件中无法使用。
上述代码中,以下代码:
- void print()
- {
- printf("这是静态函数,只能在本文件中使用\n");
- }
静态函数print的定义。
上述代码中,以下代码:
- void call()
- {
- print();
- printf("静态变量:%d\n", ex);
- }
普通函数call的定义。由于静态函数print和静态变量ex,都与函数call在同一个文件中,所以以下语句:
- print();
- printf("静态变量:%d\n", ex);
对静态函数print的调用和静态变量ex的使用是合法的。
步骤五:main文件
main.h文件,代码如下所示:
- #ifndef main_h
- #define main_h
- #if defined(SHORT)
- #define FILE "short.h"
- #elif defined(STANDARD)
- #define FILE "standard.h"
- #elif defined(LONG)
- #define FILE "long.h"
- #endif
- #include FILE
- #endif
上述代码中,以下代码:
- #if defined(SHORT)
- #define FILE "short.h"
使用条件编译语句#if判断宏名SHORT是否定义,如果定义则定义宏名FILE为"short.h"。
上述代码中,以下代码:
- #elif defined(STANDARD)
- #define FILE "standard.h"
使用条件编译语句#elif判断宏名STANDARD是否定义,如果定义则定义宏名FILE为"standard.h"。
上述代码中,以下代码:
- #elif defined(LONG)
- #define FILE "long.h"
使用条件编译语句#elif判断宏名LONG是否定义,如果定义则定义宏名FILE为"long.h"。
上述代码中,以下代码:
- #include FILE
包含头文件FILE。
main.c文件,代码如下所示:
- #include <stdio.h>
- #define STANDARD
- #include "main.h"
- #include "static.h"
- extern int ex;
- int main()
- {
- printf("5 + 3 = %d\n", add(5, 3));
- printf("5 - 3 = %d\n", sub(5, 3));
- //print();
- //printf("静态变量:%d\n", ex);
- call();
- return 0;
- }
上述代码中,以下代码:
- #define STANDARD
- #include "main.h"
定义宏名STANDARD,这样在main.h中将执行#include "standard.h"。
上述代码中,以下代码:
- extern int ex;
声明一个外部变量ex。变量ex定义在static.c中,但由于变量ex被定义成静态变量,所以此语句没有意义。
上述代码中,以下代码:
- printf("5 + 3 = %d\n", add(5, 3));
- printf("5 - 3 = %d\n", sub(5, 3));
调用的函数add和函数sub是被定义在standard.c中的函数add和函数sub。
上述代码中,以下代码:
- //print();
调用函数print是非法的。因为函数print是静态函数,只能在static.c文件中被调用。
上述代码中,以下代码:
- //printf("静态变量:%d\n", ex);
使用变量ex是非法的。因为变量ex是静态变量,只能在static.c文件中被使用。
上述代码中,以下代码:
- call();
调用call函数是合法的,因为函数call不是静态函数。
本案例的完整代码如下所示:
short.h文件,代码如下所示:
- #ifndef short_h
- #define short_h
- short add(short a, short b);
- short sub(short a, short b);
- #endif
short.c文件,代码如下所示:
- #include "short.h"
- short add(short a, short b)
- {
- return a + b;
- }
- short sub(short a, short b)
- {
- return a - b;
- }
standard.h文件,代码如下所示:
- #ifndef int_h
- #define int_h
- int add(int a, int b);
- int sub(int a, int b);
- #endif
standard.c文件,代码如下所示:
- #include "standard.h"
- int add(int a, int b)
- {
- return a + b;
- }
- int sub(int a, int b)
- {
- return a - b;
- }
long.h文件,代码如下所示:
- #ifndef long_h
- #define long_h
- long add(long a, long b);
- long sub(long a, long b);
- #endif
long.c文件,代码如下所示:
- #include "long.h"
- long add(long a, long b)
- {
- return a + b;
- }
- long sub(long a, long b)
- {
- return a - b;
- }
static.h文件,代码如下所示:
- #ifndef int_h
- #define int_h
- static void print();
- void call();
- #endif
static.c文件,代码如下所示:
- #include <stdio.h>
- #include "static.h"
- static int ex = 10;
- void print()
- {
- printf("这是静态函数,只能在本文件中使用\n");
- }
- void call()
- {
- print();
- printf("静态变量:%d\n", ex);
- }
main.h文件,代码如下所示:
- #ifndef main_h
- #define main_h
- #if defined(SHORT)
- #define FILE "short.h"
- #elif defined(STANDARD)
- #define FILE "standard.h"
- #elif defined(LONG)
- #define FILE "long.h"
- #endif
- #include FILE
- #endif
main.c文件,代码如下所示:
- #include <stdio.h>
- #define STANDARD
- #include "main.h"
- #include "static.h"
- extern int ex;
- int main()
- {
- printf("5 + 3 = %d\n", add(5, 3));
- printf("5 - 3 = %d\n", sub(5, 3));
- //print();
- //printf("静态变量:%d\n", ex);
- call();
- return 0;
- }
分别使用静态初始化和动态初始化的方式对数组进行赋值,并循环打印数组元素。
实现此案例需要按照如下步骤进行。
步骤一:input文件
input.h,代码如下所示:
- #ifndef input_h
- #define input_h
- void input();
- #endif
上述代码中,以下代码:
- void input();
声明了一个函数input。
input.c,代码如下所示:
- #include <stdio.h>
- extern int num;
- void input()
- {
- printf("请输入一个整数:");
- scanf("%d", &num);
- }
上述代码中,以下代码:
- extern int num;
声明了一个外部变量num。该变量定义在main.c中。
上述代码中,以下代码:
- void input()
- {
- printf("请输入一个整数:");
- scanf("%d", &num);
- }
定义了函数input。
步骤二:output文件
output.h,代码如下所示:
- #ifndef output_h
- #define output_h
- void output();
- #endif
上述代码中,以下代码:
- void output();
声明了一个函数output。
output.c,代码如下所示:
- #include <stdio.h>
- extern int num;
- void output()
- {
- printf("%d\n", num);
- }
上述代码中,以下代码:
- extern int num;
声明了一个外部变量num。该变量定义在main.c中。
上述代码中,以下代码:
- void output()
- {
- printf("%d\n", num);
- }
定义了函数output。
步骤三:main文件
代码如下所示:
- #include <stdio.h>
- #include "input.h"
- #include "output.h"
- int num;
- int main()
- {
- input();
- output();
- return 0;
- }
上述代码中,以下代码:
- int num;
定义了一个全局变量num。
上述代码中,以下代码:
- input();
- output();
调用函数input,对变量num进行输入。
调用函数output,对变量num进行输出。
步骤四:makefile文件
代码如下所示:
- main:main.o input.o output.o
- gcc main.c input.c output.c
- main.o:main.c
- gcc main.c -c
- input.o:input.c
- gcc input.c -c
- output.o:output.c
- gcc output.c -c
可以使用makefile文件来一次性执行多条命令(批处理命令)。makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
本案例的完整代码如下所示:
input.h,代码如下所示:
- #ifndef input_h
- #define input_h
- void input();
- #endif
input.c,代码如下所示:
- #include <stdio.h>
- extern int num;
- void input()
- {
- printf("请输入一个整数:");
- scanf("%d", &num);
- }
output.h,代码如下所示:
- #ifndef output_h
- #define output_h
- void output();
- #endif
output.c,代码如下所示:
- #include <stdio.h>
- extern int num;
- void output()
- {
- printf("%d\n", num);
- }
main文件,代码如下所示:
- #include <stdio.h>
- #include "input.h"
- #include "output.h"
- int num;
- int main()
- {
- input();
- output();
- return 0;
- }
makefile文件,代码如下所示:
- main:main.o input.o output.o
- gcc main.c input.c output.c
- main.o:main.c
- gcc main.c -c
- input.o:input.c
- gcc input.c -c
- output.o:output.c
- gcc output.c -c
定义测试结构体,并进行声明变量和初始化。
实现此案例需要按照如下步骤进行。
步骤一:结构的声明和初始化
代码如下所示:
- #include <stdio.h>
- struct student
- {
- int id;
- char name[10];
- }stu1;
- int main()
- {
- stu1.id = 110;
- strcpy(stu1.name, "zhangsan");
- printf("学号:%d, 姓名:%s", stu1.id, stu1.name);
- struct student stu2 = {112, "lisi"};
- printf("学号:%d, 姓名:%s", stu2.id, stu2.name);
- return 0;
- }
上述代码中,以下代码:
- struct student
- {
- int id;
- char name[10];
- }stu1;
定义学生结构体student。该结构体有两个成员,第一个成员是学号id,第二个成员是姓名name。在定义结构体student的同时定义了结构体变量stu1。
上述代码中,以下代码:
- stu1.id = 110;
- strcpy(stu1.name, "zhangsan");
- printf("学号:%d, 姓名:%s", stu1.id, stu1.name);
首先,将结构体变量stu1的学号成员赋值为110。
然后,将结构体变量stu1的姓名成员赋值为"zhangsan"。
最后,输出结构体变量stu1。
上述代码中,以下代码:
- struct student stu2 = {112, "lisi"};
- printf("学号:%d, 姓名:%s", stu2.id, stu2.name);
首先,定义了另一个结构体变量stu2,并对其进行初始化,将学号成员初始化为112,姓名成员初始化为"lisi"。
然后,输出结构体变量stu2。
本案例的完整代码如下所示:
- #include <stdio.h>
- struct student
- {
- int id;
- char name[10];
- }stu1;
- int main()
- {
- stu1.id = 110;
- strcpy(stu1.name, "zhangsan");
- printf("学号:%d, 姓名:%s", stu1.id, stu1.name);
- struct student stu2 = {112, "lisi"};
- printf("学号:%d, 姓名:%s", stu2.id, stu2.name);
- return 0;
- }
定义结构点point,计算每个点离(0,0)的距离。
再定义结构rect(矩形),由两个点组成,计算矩形的面积。
实现此案例需要按照如下步骤进行。
步骤一:结构的声明和初始化(续1)
代码如下所示:
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- struct point
- {
- int x;
- int y;
- };
- struct rect
- {
- struct point left_top;
- struct point right_bottom;
- };
- int main()
- {
- struct point dot = {10, 20};
- int dis = sqrt(dot.x * dot.x + dot.y * dot.y);
- printf("点(%d,%d)到原点(0,0)的距离是:%d\n", dot.x, dot.y, dis);
- struct point a = {10, 10};
- struct point b = {50, 30};
- struct rect r = {a, b};
- int area = abs(r.left_top.x - r.right_bottom.x) * abs(r.left_top.y - r.right_bottom.y);
- printf("矩形的面积是:%d\n", area);
- return 0;
- }
上述代码中,以下代码:
- struct point
- {
- int x;
- int y;
- };
定义一个结构体point,该结构体有两个成员,x轴坐标x,y轴坐标y。
上述代码中,以下代码:
- struct rect
- {
- struct point left_top;
- struct point right_bottom;
- };
定义一个结构体rect,该结构体有两个成员,左上角点坐标left_top,右下角点坐标right_bottom。
上述代码中,以下代码:
- struct point dot = {10, 20};
定义一个结构体point的变量dot,并初始化为(10,20)。
上述代码中,以下代码:
- int dis = sqrt(dot.x * dot.x + dot.y * dot.y);
计算点dot到原点的距离。
上述代码中,以下代码:
- struct point a = {10, 10};
- struct point b = {50, 30};
- struct rect r = {a, b};
首先,定义两个结构体point的变量a和b,并初始化为(10,10)和(50,30)。
然后,定义结构体rect的变量r,并用上述两个结构体point的变量a和b初始化。
上述代码中,以下代码:
- int area = abs(r.left_top.x - r.right_bottom.x) * abs(r.left_top.y - r.right_bottom.y);
计算矩形r面积。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- struct point
- {
- int x;
- int y;
- };
- struct rect
- {
- struct point left_top;
- struct point right_bottom;
- };
- int main()
- {
- struct point dot = {10, 20};
- int dis = sqrt(dot.x * dot.x + dot.y * dot.y);
- printf("点(%d,%d)到原点(0,0)的距离是:%d\n", dot.x, dot.y, dis);
- struct point a = {10, 10};
- struct point b = {50, 30};
- struct rect r = {a, b};
- int area = abs(r.left_top.x - r.right_bottom.x) * abs(r.left_top.y - r.right_bottom.y);
- printf("矩形的面积是:%d\n", area);
- return 0;
- }
定义一个包含月份的名字和这个月天数的结构,用一个结构的数组保存一年中的所有月份和天数,在每个结构中保存一个月的名字和天数。
月份英文:January、February、March、April、May、June、July、August、September、October、November、December。
实现此案例需要按照如下步骤进行。
步骤一:结构的声明和初始化(续2)
代码如下所示:
- #include <stdio.h>
- struct month
- {
- char name[10];
- int days;
- };
- int main()
- {
- struct month m[12] = {
- {"January", 31},
- {"February", 28},
- {"March", 31},
- {"April", 30},
- {"May", 31},
- {"June", 30},
- {"July", 31},
- {"August", 31},
- {"September", 30},
- {"October", 31},
- {"November", 30},
- {"December", 31}};
- for (int i = 0; i < 12; i++)
- printf("%d月的名字是:%s,天数是:%d\n", i + 1, m[i].name, m[i].days);
- return 0;
- }
上述代码中,以下代码:
- struct month
- {
- char name[10];
- int days;
- };
定义一个结构体month,该结构体有两个成员,该月的英文名字和该月的天数。
上述代码中,以下代码:
- struct month m[12] = {
- {"January", 31},
- {"February", 28},
- {"March", 31},
- {"April", 30},
- {"May", 31},
- {"June", 30},
- {"July", 31},
- {"August", 31},
- {"September", 30},
- {"October", 31},
- {"November", 30},
- {"December", 31}};
定义了一个结构体month的数组m,该数组有12个元素,每个元素代表一年中的一个月。定义数组m之后,对其进行了初始化。
注意:初始化时,每个数组元素的值用{}括起来。
本案例的完整代码如下所示:
- #include <stdio.h>
- struct month
- {
- char name[10];
- int days;
- };
- int main()
- {
- struct month m[12] = {
- {"January", 31},
- {"February", 28},
- {"March", 31},
- {"April", 30},
- {"May", 31},
- {"June", 30},
- {"July", 31},
- {"August", 31},
- {"September", 30},
- {"October", 31},
- {"November", 30},
- {"December", 31}};
- for (int i = 0; i < 12; i++)
- printf("%d月的名字是:%s,天数是:%d\n", i + 1, m[i].name, m[i].days);
- return 0;
- }
对比结构做参数的两种方式,使用->操作成员。
实现此案例需要按照如下步骤进行。
步骤一:结构做参数
代码如下所示:
- #include <stdio.h>
- #include <string.h>
- struct student
- {
- int id;
- char name[10];
- }stu;
- void print1(struct student stu)
- {
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- }
- void print2(struct student *p)
- {
- printf("学号:%d, 姓名:%s\n", p->id, p->name);
- }
- int main()
- {
- stu.id = 110;
- strcpy(stu.name, "zhangsan");
- print1(stu);
- print2(&stu);
- return 0;
- }
上述代码中,以下代码:
- struct student
- {
- int id;
- char name[10];
- }stu;
定义学生结构体student。该结构体有两个成员,第一个成员是学号id,第二个成员是姓名name。在定义结构体student的同时定义了结构体变量stu。
上述代码中,以下代码:
- void print1(struct student stu)
- {
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- }
定义了一个函数print1,用于打印结构体student的变量的值。该函数有一个参数,是结构体student的变量stu。这是值传递的方法。结构体student的变量stu将是实参的副本。
上述代码中,以下代码:
- void print2(struct student *p)
- {
- printf("学号:%d, 姓名:%s\n", p->id, p->name);
- }
定义了一个函数print2,用于打印结构体student的变量的值。该函数有一个参数,是结构体student的指针变量p。这是地址传递的方法。结构体student的指针变量p将指向实参。该函数中,p->id是用指针p指向的结构体student的变量的id成员。
上述代码中,以下代码:
- stu.id = 110;
- strcpy(stu.name, "zhangsan");
首先,将结构体student的变量stu的id成员赋值为110。
然后,将结构体student的变量stu的name成员赋值为"zhangsan"。
上述代码中,以下代码:
- print1(stu);
调用值传递方法的print1函数,实参为结构体student的变量stu。
上述代码中,以下代码:
- print2(&stu);
调用地址传递方法的print2函数,实参为结构体student的变量stu的地址。
本案例的完整代码如下所示:
- #include <stdio.h>
- #include <string.h>
- struct student
- {
- int id;
- char name[10];
- }stu;
- void print1(struct student stu)
- {
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- }
- void print2(struct student *p)
- {
- printf("学号:%d, 姓名:%s\n", p->id, p->name);
- }
- int main()
- {
- stu.id = 110;
- strcpy(stu.name, "zhangsan");
- print1(stu);
- print2(&stu);
- return 0;
- }
测试直接返回结构的问题,并实现用结构指针参数带出数据。
实现此案例需要按照如下步骤进行。
步骤一:结构做返回值
代码如下所示:
- #include <stdio.h>
- struct student
- {
- int id;
- char name[10];
- };
- struct student input1()
- {
- struct student stu;
- printf("输入学号:");
- scanf("%d", &stu.id);
- printf("输入姓名:");
- scanf("%s", stu.name);
- return stu;
- }
- void input2(struct student *p)
- {
- printf("输入学号:");
- scanf("%d", &p->id);
- printf("输入姓名:");
- scanf("%s", p->name);
- }
- int main()
- {
- struct student stu;
- stu = input1();
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- input2(&stu);
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- return 0;
- }
上述代码中,以下代码:
- struct student
- {
- int id;
- char name[10];
- };
定义学生结构体student。该结构体有两个成员,第一个成员是学号id,第二个成员是姓名name。
上述代码中,以下代码:
- struct student input1()
- {
- struct student stu;
- printf("输入学号:");
- scanf("%d", &stu.id);
- printf("输入姓名:");
- scanf("%s", stu.name);
- return stu;
- }
定义一个函数input1,用于输入。该函数中,以下语句:
- struct student stu;
定义了一个局部结构体student的变量stu。该函数中,以下语句:
- printf("输入学号:");
- scanf("%d", &stu.id);
- printf("输入姓名:");
- scanf("%s", stu.name);
输入学号和姓名。该函数中,以下语句:
- return stu;
返回结构体student的变量stu。
上述代码中,以下代码:
- void input2(struct student *p)
- {
- printf("输入学号:");
- scanf("%d", &p->id);
- printf("输入姓名:");
- scanf("%s", p->name);
- }
定义一个函数input2,用于输入,该函数有一个参数,是指向结构体student的指针变量p。该函数中,以下语句:
- printf("输入学号:");
- scanf("%d", &p->id);
- printf("输入姓名:");
- scanf("%s", p->name);
将学号和姓名输入到结构体student的指针变量p指向的实参。
上述代码中,以下代码:
- int main()
- {
- struct student stu;
- stu = input1();
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
在主函数中,定义结构体student的变量stu,用于接收函数input1的返回值。
上述代码中,以下代码:
- input2(&stu);
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
在主函数中,将结构体student的变量stu的地址作为实参传入input2,以输入其值。
本案例的完整代码如下所示:
- #include <stdio.h>
- struct student
- {
- int id;
- char name[10];
- };
- struct student input1()
- {
- struct student stu;
- printf("输入学号:");
- scanf("%d", &stu.id);
- printf("输入姓名:");
- scanf("%s", stu.name);
- return stu;
- }
- void input2(struct student *p)
- {
- printf("输入学号:");
- scanf("%d", &p->id);
- printf("输入姓名:");
- scanf("%s", p->name);
- }
- int main()
- {
- struct student stu;
- stu = input1();
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- input2(&stu);
- printf("学号:%d, 姓名:%s\n", stu.id, stu.name);
- return 0;
- }
对齐是指由于内存分配会将结构中的变量分配到内存的边界上,以方便访问。每个成员放的位置是从本身长度的倍数位开始放。
补齐是指整个结构变量的长度要保持内部最长成员(超过4以4计)的倍数。如果不够,则补齐。
实现此案例需要按照如下步骤进行。
步骤一:结构的对齐和补齐
代码如下所示:
- #include <stdio.h>
- struct size
- {
- char c;
- int i;
- };
- int main()
- {
- printf("sizeof(size) = %ld\n", sizeof(struct size));
- return 0;
- }
上述代码中,以下代码:
- struct size
- {
- char c;
- int i;
- };
定义一个结构体size,该结构体有两个成员,字符型变量c和整型变量i。
上述代码中,以下代码:
- printf("sizeof(size) = %ld\n", sizeof(struct size));
输出结构体size所占的字节数。从输出结果可知是8个字节。为什么不是5个字节呢?
原因是字符对齐的概念。当一个结构体被分配存储空间时,分配的方法是这样的:
首先,找到结构体中占字节数最多的成员,本案例中是整型变量i。
然后,以该成员所占的字节数为单位,为结构体的每个成员分配存储空间。在本案例中,为第一个成员字符型变量c分配4个字节,该成员用掉1个字节,剩下3个字节。字符型变量c所占的那个字节的编号设为0,剩下的3个字节编号依次为1、2、3。
最后,为第二个成员整型变量i分配存储空间,由于剩下的3个字节的编号依次为1、2、3,用这些编号对整型变量i所占字节数4求余,结果都不为0,所以剩下的3个字节都跳过。而再分配4个字节给整型变量i。
所以本案例的输出结果为8个字节,而不是5个字节。因为有三个字节没有用。
本案例的完整代码如下所示:
- #include <stdio.h>
- struct size
- {
- char c;
- int i;
- };
- int main()
- {
- printf("sizeof(size) = %ld\n", sizeof(struct size));
- return 0;
- }
联合就是一块内存对应不同的类型,并起了不同的名字,在使用时按照名字切换类型,而不是用类型转换。
实现此案例需要按照如下步骤进行。
步骤一:联合的基本用法
代码如下所示:
- #include <stdio.h>
- union data
- {
- int a;
- int b;
- int c;
- };
- int main()
- {
- union data d;
- d.a = 10;
- printf("%d %d %d\n", d.a, d.b, d.c);
- d.b = 20;
- printf("%d %d %d\n", d.a, d.b, d.c);
- d.c = 30;
- printf("%d %d %d\n", d.a, d.b, d.c);
- return 0;
- }
上述代码中,以下代码:
- union data
- {
- int a;
- int b;
- int c;
- };
定义了一个联合data,该联合中有三个成员,这三个成员共用4个字节。
上述代码中,以下代码:
- union data d;
- d.a = 10;
- printf("%d %d %d\n", d.a, d.b, d.c);
首先,定义一个联合data的变量d。
然后,将联合data的变量d的第一个成员a赋值为10。
最后,使用printf输出联合data的三个成员的值。从输出结果可以看出,值都相同。而且,后两个成员未赋值。原因是联合data的三个成员共用4个字节。
上述代码中,以下代码:
- d.b = 20;
- printf("%d %d %d\n", d.a, d.b, d.c);
将联合data的变量d的第二个成员b赋值为20。从输出结果可以看出,联合data的三个成员的值都相同。原因是联合data的三个成员共用4个字节。
上述代码中,以下代码:
- d.c = 30;
- printf("%d %d %d\n", d.a, d.b, d.c);
将联合data的变量d的第三个成员c赋值为30。从输出结果可以看出,联合data的三个成员的值还是都相同。原因还是联合data的三个成员共用4个字节。
本案例的完整代码如下所示:
- #include <stdio.h>
- union data
- {
- int a;
- int b;
- int c;
- };
- int main()
- {
- union data d;
- d.a = 10;
- printf("%d %d %d\n", d.a, d.b, d.c);
- d.b = 20;
- printf("%d %d %d\n", d.a, d.b, d.c);
- d.c = 30;
- printf("%d %d %d\n", d.a, d.b, d.c);
- return 0;
- }
枚举是一个整型常量的列表,一般来说,值是有限个。每个值都是枚举常量(整型)。可以定义时指定值,也可以多个枚举名表示同一个值。枚举常量可看成字面量。
实现此案例需要按照如下步骤进行。
步骤一:枚举的基本用法
代码如下所示:
- #include <stdio.h>
- enum WEEK
- {
- Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday,
- };
- int main()
- {
- int day;
- printf("请输入今天是星期几:");
- scanf("%d", &day);
- switch(day)
- {
- case Monday:
- printf("星期一\n");
- break;
- case Tuesday:
- printf("星期二\n");
- break;
- case Wednesday:
- printf("星期三\n");
- break;
- case Thursday:
- printf("星期四\n");
- break;
- case Friday:
- printf("星期五\n");
- break;
- case Saturday:
- printf("星期六\n");
- break;
- case Sunday:
- printf("星期日\n");
- break;
- }
- return 0;
- }
上述代码中,以下代码:
- enum WEEK
- {
- Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday,
- };
定义了一个枚举WEEK,是一个整型常量的列表,Monday是1,后面的值依次加1。
上述代码中,以下代码:
- int day;
- printf("请输入今天是星期几:");
- scanf("%d", &day);
首先,定义一个整型变量day,用于存储星期几的整数。
然后,使用printf提示输出输入星期几。
最后,使用scanf输入星期几到整型变量day中。
上述代码中,以下代码:
- switch(day)
- {
- case Monday:
- printf("星期一\n");
- break;
- case Tuesday:
- printf("星期二\n");
- break;
- case Wednesday:
- printf("星期三\n");
- break;
- case Thursday:
- printf("星期四\n");
- break;
- case Friday:
- printf("星期五\n");
- break;
- case Saturday:
- printf("星期六\n");
- break;
- case Sunday:
- printf("星期日\n");
- break;
- }
使用switch结构将整形星期几转换成字符串的星期几。其中每个case后面为一个枚举值。
本案例的完整代码如下所示:
- #include <stdio.h>
- enum WEEK
- {
- Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday,
- };
- int main()
- {
- int day;
- printf("请输入今天是星期几:");
- scanf("%d", &day);
- switch(day)
- {
- case Monday:
- printf("星期一\n");
- break;
- case Tuesday:
- printf("星期二\n");
- break;
- case Wednesday:
- printf("星期三\n");
- break;
- case Thursday:
- printf("星期四\n");
- break;
- case Friday:
- printf("星期五\n");
- break;
- case Saturday:
- printf("星期六\n");
- break;
- case Sunday:
- printf("星期日\n");
- break;
- }
- return 0;
- }
标签:
原文地址:http://blog.csdn.net/opera95/article/details/51201817