1 输入一个整数,求春夏秋冬

1.1 问题

在实际应用中,有的变量只有几种可能取值。如人的性别只有两种可能取值,星期只有七种可能取值。在 C 语言中对这样取值比较特殊的变量可以定义为枚举类型。所谓枚举是指将变量的值一一列举出来,变量只限于列举出来的值的范围内取值。

本案例需要使用交互的方式判断:用户从控制台输入一个整数,由程序判断该整数是春夏秋冬哪个季节。春夏秋冬分别用一个枚举常量表示。

程序交互过程如图-1所示:

图-1

1.2 方案

首先,在程序中定义一个枚举,在枚举中定义春夏秋冬四个常量。然后,从控制台输入一个整数,接着,使用switch结构判断输入的整数是哪个季节,并输出相应季节的名称。如果输入的整数不在枚举常量的范围之内,则显示输入错误。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义枚举

代码如下:

 
  1. #include <stdio.h>
  2. enum Season
  3. {
  4. SPRING,
  5. SUMMER,
  6. AUTUMN,
  7. WINTER,
  8. };
  9. int main(int argc, const char * argv[])
  10. {
  11. return 0;
  12. }

步骤二:输入一个整数

定义一个变量,用于存储从控制台输入的整数。

代码如下:

  1. #include <stdio.h>
  2. enum Season
  3. {
  4. SPRING,
  5. SUMMER,
  6. AUTUMN,
  7. WINTER,
  8. };
  9. int main(int argc, const char * argv[])
  10. {
  11. int season;
  12. printf("请输入一个整数:");
  13. scanf("%d", &season);
  14. return 0;
  15. }

步骤三:季节判断

使用switch结构,判断输入的整数属于哪个季节。

  1. #include <stdio.h>
  2. enum Season
  3. {
  4. SPRING,
  5. SUMMER,
  6. AUTUMN,
  7. WINTER,
  8. };
  9. int main(int argc, const char * argv[])
  10. {
  11. int season;
  12. printf("请输入一个整数:");
  13. scanf("%d", &season);
  14. switch (season)
  15. {
  16. case SPRING:
  17. printf("对应的季节是:spring\n");
  18. break;
  19. case SUMMER:
  20. printf("对应的季节是:summer\n");
  21. break;
  22. case AUTUMN:
  23. printf("对应的季节是:autumn\n");
  24. break;
  25. case WINTER:
  26. printf("对应的季节是:winter\n");
  27. break;
  28. default:
  29. printf("error\n");
  30. }
  31. return 0;
  32. }

1.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. enum Season
  3. {
  4. SPRING,
  5. SUMMER,
  6. AUTUMN,
  7. WINTER,
  8. };
  9. int main(int argc, const char * argv[])
  10. {
  11. int season;
  12. printf("请输入一个整数:");
  13. scanf("%d", &season);
  14. switch (season)
  15. {
  16. case SPRING:
  17. printf("对应的季节是:spring\n");
  18. break;
  19. case SUMMER:
  20. printf("对应的季节是:summer\n");
  21. break;
  22. case AUTUMN:
  23. printf("对应的季节是:autumn\n");
  24. break;
  25. case WINTER:
  26. printf("对应的季节是:winter\n");
  27. break;
  28. default:
  29. printf("error\n");
  30. }
  31. return 0;
  32. }

2 用参数返回字符串

2.1 问题

用参数返回一个值,该参数需要用到指针,使用形参指针可以在一个函数内部修改它所指向的内容,如下代码所示:

  1. void func(int *x)
  2. {
  3. *x = 10;
  4. }
  5. int main()
  6. {
  7. int a = 0;
  8. func(&a);
  9. printf(“%d”, a);
  10. }

上述代码中,在主函数内将变量a的地址作为实参传递给函数func的形参x,而在函数func中,修改指针x指向的内容,即主函数中的变量a,此时的修改是可以带回主函数的,即主函数中的变量a将变为10。

但是,如果我们修改的不是指针所指向的内容,而是指针本身,那么,这样的修改是无法带回主函数的。如下面代码所示:

  1. void func(int *x)
  2. {
  3. static int data = 20;
  4. x = &data;
  5. }
  6. int main()
  7. {
  8. int a = 0;
  9. func(&a);
  10. printf(“%d”, a);
  11. }

2.2 方案

在函数调用的过程中,如果我们要修改的不是指针所指向的内容,而是指针本身,那么,这样的修改必须通过二级指针来实现。

所谓的二级指针,是指指向指针的指针,如下代码所示:

  1. int a;
  2. int *p = &a;
  3. int **p1 = &p;

上述代码中,指针变量p是一级指针,它直接指向一个整型变量;而变量p1,则是一个二级指针,因为它指向的是另一个指针变量p,也就是说,p1是指向指针p的指针,即指针的指针。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义返回字符串的函数

该函数需要使用二级指针,即指针的指针。因为在函数中,需要修改的是指针本身,这样就需要将指针本身的地址(也就是指针变量的地址)作为参数传递过来。

代码如下:

  1. #include <stdio.h>
  2. void getString(char **str)
  3. {
  4. *str = "This is a string.\n";
  5. }
  6. int main()
  7. {
  8. return 0;
  9. }

上述代码中,指针str为一个二级指针。

步骤二:在主程序中,获得并打印返回的字符串

代码如下:

  1. #include <stdio.h>
  2. void getString(char **str)
  3. {
  4. *str = "This is a string.\n";
  5. }
  6. int main()
  7. {
  8. char *string = NULL;
  9. getString(&string);
  10. printf("%s",string);
  11. return 0;
  12. }

上述代码中,指针变量str得到的是指针变量string的地址,所以str为二级指针,而对*str的修改就是对string的修改。

2.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. void getString(char **str)
  3. {
  4. *str = "This is a string.\n";
  5. }
  6. int main()
  7. {
  8. char *string = NULL;
  9. getString(&string);
  10. printf("%s",string);
  11. return 0;
  12. }

3 打印任意类型变量的内存数据

3.1 问题

void*表示“空类型指针”,与void不同,void*表示“任意类型的指针”或表示“该指针与一地址值相关,但是不清楚在此地址上的对象的类型”。C是静态类型的语言,定义变量就会分配内存,然而,不同类型的变量所占内存不同,如果定义一个任意类型的变量,如何为其分配内存呢?所以,C中没有任意类型的变量。但是,所有指针类型的变量,无论是int*、char*、string*、Student*等等,他们的内存空间都是相同的,所以可以定义“任意类型的指针”。

3.2 方案

void*类型的指针可以指向任意类型的变量,如下面代码:

  1. int a;
  2. void* p = &a;
  3. float f;
  4. p = &f;

上述代码都是正确的,指针变量p既可以指向整型变量a,同时,它还可以指向浮点型变量f。

将一个void*类型的指针指向的内容赋值给一个确定类型的变量时,不能直接赋值,如下面代码:

  1. int a = 10;
  2. void* p = &a;
  3. int b = *p;//error

上述代码的第三行是错误的,因为void*类型的指针指向的内容的类型是不确定的,所以是无法进行赋值的。如果非要进行赋值,必须先将void*类型的指针强转成确定的数据类型,如下面代码:

  1. int b = *(int*)p;

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写打印函数

该函数带有一个void*类型的指针,用于接收任意类型的数据,同时还带有一个整型变量,用于表示void*类型的指针指向的内容的数据类型。在函数体中,使用一个switch结构,用整型变量来区分不同的数据类型,以打印不同的数据。

代码如下:

  1. #include <stdio.h>
  2. void print(void *data, int type)
  3. {
  4. switch (type)
  5. {
  6. case 0:
  7. printf("%d\n", *(int*)data);
  8. break;
  9. case 1:
  10. printf("%f\n", *(float*)data);
  11. break;
  12. case 2:
  13. printf("%lf\n", *(double*)data);
  14. break;
  15. case 3:
  16. printf("%c\n", *(char*)data);
  17. break;
  18. }
  19. }
  20. int main()
  21. {
  22. return 0;
  23. }

步骤二:主函数打印不同类型的数据

代码如下:

  1. #include <stdio.h>
  2. void print(void *data, int type)
  3. {
  4. switch (type)
  5. {
  6. case 0:
  7. printf("%d\n", *(int*)data);
  8. break;
  9. case 1:
  10. printf("%f\n", *(float*)data);
  11. break;
  12. case 2:
  13. printf("%lf\n", *(double*)data);
  14. break;
  15. case 3:
  16. printf("%c\n", *(char*)data);
  17. break;
  18. }
  19. }
  20. int main()
  21. {
  22. int a = 10;
  23. print(&a, 0);
  24. float f = 3.14f;
  25. print(&f, 1);
  26. double d = 1.2345;
  27. print(&d, 2);
  28. char c = 'a';
  29. print(&c, 3);
  30. return 0;
  31. }

3.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. void print(void *data, int type)
  3. {
  4. switch (type)
  5. {
  6. case 0:
  7. printf("%d\n", *(int*)data);
  8. break;
  9. case 1:
  10. printf("%f\n", *(float*)data);
  11. break;
  12. case 2:
  13. printf("%lf\n", *(double*)data);
  14. break;
  15. case 3:
  16. printf("%c\n", *(char*)data);
  17. break;
  18. }
  19. }
  20. int main()
  21. {
  22. int a = 10;
  23. print(&a, 0);
  24. float f = 3.14f;
  25. print(&f, 1);
  26. double d = 1.2345;
  27. print(&d, 2);
  28. char c = 'a';
  29. print(&c, 3);
  30. return 0;
  31. }

4 排序函数使用函数指针

4.1 问题

函数指针是一种指针,一个指向函数入口地址的指针。一个函数需要占用一段内存空间,这段空间的起始地址是函数的入口地址。可以定义一个指针变量,指向函数的入口地址,然后通过这个指针变量调用函数。

4.2 方案

一种排序函数,一般只能有一种排序规则。例如:要么从大到小排序,要么从小到大排序,或者特殊的规则,比如按照对3求余数的排序。通过使用函数指针,可以使排序函数将排序规则独立。这样在对指定的数据进行排序的时候,同时指定排序规则,使得排序函数第一次被调用时可以从大到小排序,第二次被调用时又可以从小到大排序。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:在主程序中,定义一个数组

代码如下:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  5. return 0;
  6. }

步骤二:定义数组打印函数

代码如下:

  1. #include <stdio.h>
  2. void print(int* a, int n)
  3. {
  4. for (int i=0; i<n; i++) {
  5. printf("%d ", a[i]);
  6. }
  7. printf("\n");
  8. }
  9. int main()
  10. {
  11. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  12. print(a, 10);
  13. return 0;
  14. }

步骤三:定义带排序规则的排序函数

排序方法采用冒泡方法。

代码如下:

  1. #include <stdio.h>
  2. void print(int* a, int n)
  3. {
  4. for (int i=0; i<n; i++) {
  5. printf("%d ", a[i]);
  6. }
  7. printf("\n");
  8. }
  9. int rule1(int x, int y)
  10. {
  11. return x - y;
  12. }
  13. void sort(int* a, int n, int (*f)(int, int))
  14. {
  15. for (int i=0; i<n-1; i++) {
  16. for (int j=0; j<n-i-1; j++) {
  17. if (f(a[j], a[j+1])>0) {
  18. int t = a[j];
  19. a[j] = a[j+1];
  20. a[j+1] = t;
  21. }
  22. }
  23. }
  24. }
  25. int main()
  26. {
  27. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  28. print(a, 10);
  29. sort(a, 10, rule1);
  30. print(a, 10);
  31. return 0;
  32. }

上述代码中,以下代码:

  1. int rule1(int x, int y)
  2. {
  3. return x - y;
  4. }

是排序规则,该函数返回形参x与y的差,如果返回值大于0,代表x大于y;如果返回值等于0,代表x等于y;如果返回值小于0,代表x小于y。

上述代码中,以下代码:

  1. void sort(int* a, int n, int (*f)(int, int))

是排序函数的函数头,该函数是一个无返回值的函数,函数名为sort,函数带有三个形参,第一个形参是一个整型指针变量,它用于接收需要排序的数据;第二个形参是一个整型变量,它用于接收需要排序的数据的个数;第三个形参是一个函数的指针变量,int表示该函数指针变量指向的函数的返回值为整型,f为函数指针变量的变量名,(int,int)代表该函数指针变量指向的函数有两个形参。

在主函数中,使用以下代码调用sort函数:

  1. sort(a, 10, rule1);

其中,第一个实参a为数组a的数组名,第二个实参10为数组a的数组长度,第三个实参rule1为函数名,该函数为排序规则。

上述代码中,以下代码:

  1. if (f(a[j], a[j+1])>0) {
  2. int t = a[j];
  3. a[j] = a[j+1];
  4. a[j+1] = t;
  5. }

是使用函数指针调用函数,指针变量f作为形参,接收实参传递过来的函数的入口地址,即rule1函数,使用f(a[j],a[j+1])调用rule1函数,其中,a[j]和a[j+1]是函数指针变量f指向的函数的两个实参,即函数rule1的两个实参。

步骤四:定义其它排序规则函数

代码如下:

  1. #include <stdio.h>
  2. void print(int* a, int n)
  3. {
  4. for (int i=0; i<n; i++) {
  5. printf("%d ", a[i]);
  6. }
  7. printf("\n");
  8. }
  9. int rule1(int x, int y)
  10. {
  11. return x - y;
  12. }
  13. int rule2(int x, int y)
  14. {
  15. return y - x;
  16. }
  17. int rule3(int x, int y)
  18. {
  19. return x%3 - y%3;
  20. }
  21. void sort(int* a, int n, int (*f)(int, int))
  22. {
  23. for (int i=0; i<n-1; i++) {
  24. for (int j=0; j<n-i-1; j++) {
  25. if (f(a[j], a[j+1])>0) {
  26. int t = a[j];
  27. a[j] = a[j+1];
  28. a[j+1] = t;
  29. }
  30. }
  31. }
  32. }
  33. int main()
  34. {
  35. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  36. print(a, 10);
  37. sort(a, 10, rule1);
  38. print(a, 10);
  39. sort(a, 10, rule2);
  40. print(a, 10);
  41. sort(a, 10, rule3);
  42. print(a, 10);
  43. return 0;
  44. }

4.4 完整代码

  1. #include <stdio.h>
  2. void print(int* a, int n)
  3. {
  4. for (int i=0; i<n; i++) {
  5. printf("%d ", a[i]);
  6. }
  7. printf("\n");
  8. }
  9. int rule1(int x, int y)
  10. {
  11. return x - y;
  12. }
  13. int rule2(int x, int y)
  14. {
  15. return y - x;
  16. }
  17. int rule3(int x, int y)
  18. {
  19. return x%3 - y%3;
  20. }
  21. void sort(int* a, int n, int (*f)(int, int))
  22. {
  23. for (int i=0; i<n-1; i++) {
  24. for (int j=0; j<n-i-1; j++) {
  25. if (f(a[j], a[j+1])>0) {
  26. int t = a[j];
  27. a[j] = a[j+1];
  28. a[j+1] = t;
  29. }
  30. }
  31. }
  32. }
  33. int main()
  34. {
  35. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  36. print(a, 10);
  37. sort(a, 10, rule1);
  38. print(a, 10);
  39. sort(a, 10, rule2);
  40. print(a, 10);
  41. sort(a, 10, rule3);
  42. print(a, 10);
  43. return 0;
  44. }

5 重新分配申请的空间

5.1 问题

在堆内存中,可以使用malloc函数分配一块存储空间。malloc()函数其实就在堆内存中找一片指定大小的空间,然后将这个空间的首地址返回给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。

还可以使用realloc函数对用malloc函数分配好的空间重新分配,一般是扩大。对于realloc函数,如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回分配内存的首地址。这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小就等于新的空间大小。得到的是一块连续的内存。如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块新大小的内存。并把原来大小内存空间中的内容复制到新空间中。返回新的内存的指针。这样数据被移动了新空间,先前的空间被释放。

当使用malloc分配的空间不再使用的时候,可以使用free函数将这块空间还给堆内存,以使这块内存可以被再次使用。

5.2 方案

首先,使用malloc函数分配3个整型数据的空间。

然后,再使用realloc函数将已分配的3个整型数据的空间扩大为5个整型数据的空间。

最后,当已分配的5个整型数据的空间不再使用时,使用free函数释放。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:分配3个数据空间

使用malloc函数分配空间。

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. int *p;
  6. p = (int*)malloc(3 * sizeof(int));
  7. for (int i = 0; i < 3; i++)
  8. p[i] = i + 1;
  9. for (int i = 0; i < 3; i++)
  10. printf("%d ", p[i]);
  11. printf("\n");
  12. return 0;
  13. }

上述代码中,malloc函数的返回值为void*类型,而指针变量p是int*类型,所以需要将malloc的返回值强制转换成int*。

另外,malloc函数在使用前需要包内含stdlib.h头函数。

步骤二:重新分配为5个数据

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. int *p;
  6. p = (int*)malloc(3 * sizeof(int));
  7. for (int i = 0; i < 3; i++)
  8. p[i] = i + 1;
  9. for (int i = 0; i < 3; i++)
  10. printf("%d ", p[i]);
  11. printf("\n");
  12. p = (int*)realloc(p, 5 * sizeof(int));
  13. for (int i = 0; i < 5; i++)
  14. p[i] = i + 1;
  15. for (int i = 0; i < 5; i++)
  16. printf("%d ", p[i]);
  17. printf("\n");
  18. return 0;
  19. }

上述代码中,realloc函数将已分配为3个数据空间的指针p,重新分配为5个数据空间。realloc函数的第一个实参是原有空间的指针,第二个实参是重新分配的空间的字节个数,返回值仍然是void*类型,所以同样需要将其强制转换成int*类型。

注意:realloc函数在使用之前也需要包含stdlib.h头函数。

5.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. int *p;
  6. p = (int*)malloc(3 * sizeof(int));
  7. for (int i = 0; i < 3; i++)
  8. p[i] = i + 1;
  9. for (int i = 0; i < 3; i++)
  10. printf("%d ", p[i]);
  11. printf("\n");
  12. p = (int*)realloc(p, 5 * sizeof(int));
  13. for (int i = 0; i < 5; i++)
  14. p[i] = i + 1;
  15. for (int i = 0; i < 5; i++)
  16. printf("%d ", p[i]);
  17. printf("\n");
  18. return 0;
  19. }

6 各种类型数据的输入和输出

6.1 问题

C语言的格式化输入与输出函数分别是scanf函数和printf函数。

1) 函数 scanf() 是从标准输入流stdio (标准输入设备,一般是键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。scanf函数的语法格式为:

  1. scanf(“<格式说明字符串>”, 变量地址);

其中,变量地址要求有效,并且与格式说明的次序一致。

2) 函数printf()是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。printf()函数的语法格式为:

  1. printf("<格式化字符串>", <参量表>)。

格式化字符串由要输出的文字和数据格式说明组成。要输出的文字除了可以使用字母、数字、空格和一些数字符号以外,还可以使用一些转义字符表示特殊的含义。

3) scanf函数与printf函数在使用之前,必须包含stdio.h头函数。

6.2 方案

使用scanf函数输入一些数据,使用printf函数输出一些数据。

下表说明了scanf函数与printf函数中“格式化字符”的使用方式:

6.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义变量

定义各种数据类型的变量,代码如下所示:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int i;
  5. short int si;
  6. long int li;
  7. unsigned int ui;
  8. unsigned short int usi;
  9. unsigned long int uli;
  10. float f;
  11. double d;
  12. long double ld;
  13. char c;
  14. unsigned char uc;
  15. return 0;
  16. }

步骤二:使用scanf输入数据

代码如下所示:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. int i;
  6. short int si;
  7. long int li;
  8. unsigned int ui;
  9. unsigned short int usi;
  10. unsigned long int uli;
  11. float f;
  12. double d;
  13. scanf("%c", &c);
  14. scanf("%d", &i);
  15. scanf("%hd", &si);
  16. scanf("%ld", &li);
  17. scanf("%u", &ui);
  18. scanf("%hu", &usi);
  19. scanf("%lu", &uli);
  20. scanf("%f", &f);
  21. scanf("%lf", &d);
  22. return 0;
  23. }

步骤三:使用printf输出数据

代码如下所示:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. int i;
  6. short int si;
  7. long int li;
  8. unsigned int ui;
  9. unsigned short int usi;
  10. unsigned long int uli;
  11. float f;
  12. double d;
  13. scanf("%c", &c);
  14. scanf("%d", &i);
  15. scanf("%hd", &si);
  16. scanf("%ld", &li);
  17. scanf("%u", &ui);
  18. scanf("%hu", &usi);
  19. scanf("%lu", &uli);
  20. scanf("%f", &f);
  21. scanf("%lf", &d);
  22. printf("c=%c\n", c);
  23. printf("i=%d\n", i);
  24. printf("si=%hd\n", si);
  25. printf("li=%ld\n", li);
  26. printf("ui=%u\n", ui);
  27. printf("usi=%hu\n", usi);
  28. printf("uli=%lu\n", uli);
  29. printf("f=%f\n", f);
  30. printf("d=%lf\n", d);
  31. return 0;
  32. }

6.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. char c;
  5. int i;
  6. short int si;
  7. long int li;
  8. unsigned int ui;
  9. unsigned short int usi;
  10. unsigned long int uli;
  11. float f;
  12. double d;
  13. scanf("%c", &c);
  14. scanf("%d", &i);
  15. scanf("%hd", &si);
  16. scanf("%ld", &li);
  17. scanf("%u", &ui);
  18. scanf("%hu", &usi);
  19. scanf("%lu", &uli);
  20. scanf("%f", &f);
  21. scanf("%lf", &d);
  22. printf("c=%c\n", c);
  23. printf("i=%d\n", i);
  24. printf("si=%hd\n", si);
  25. printf("li=%ld\n", li);
  26. printf("ui=%u\n", ui);
  27. printf("usi=%hu\n", usi);
  28. printf("uli=%lu\n", uli);
  29. printf("f=%f\n", f);
  30. printf("d=%lf\n", d);
  31. return 0;
  32. }

7 整数、浮点数、字符串之间的相互转换函数

7.1 问题

1) C语言使用sprintf函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串。而下面列举的各函数在C99标准中已经不再使用。

a) itoa():将整型值转换为字符串。

b) ltoa():将长整型值转换为字符串。

c) ultoa():将无符号长整型值转换为字符串。

d) gcvt():将浮点型数转换为字符串,取四舍五入。

e) ecvt():将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。

2) C语言提供了几个标准库函数,可以将字符串转换为任意类型(整型、长整型、浮点型等)。

a) atof():将字符串转换为双精度浮点型值。

b) atoi():将字符串转换为整型值。

c) atol():将字符串转换为长整型值。

7.2 方案

本案例使用的函数:

1) sprintf函数是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。该函数的语法格式为:

  1. int sprintf( char *buffer, const char *format, [ argument] … );

其中,第一个形参是转换成的字符串存放的字符数组,第二个形参是格式化字符串,其使用方法与printf函数的格式化字符串相同,第三个形参为要转换的整数或浮点数变量。

2) atof函数是将一个字符串转换成浮点数的函数,该函数的语法格式为:

  1. double     atof(const char *);

其中,函数形参为要转换成浮点数的字符串,返回值为转换成的浮点数。

3) atoi函数是将一个字符串转换成整数的函数,该函数的语法格式为:

  1. int     atoi(const char *);

其中,函数形参为要转换成整数的字符串,返回值为转换成的整数。

4) atol函数是将一个字符串转换成长整数的函数,该函数的语法格式为:

  1. long     atol(const char *);

其中,函数形参为要转换成长整数的字符串,返回值为转换成的长整数。

7.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:整型和浮点型数据转换成字符串

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. int i = 10;
  6. char string[100] = {};
  7. sprintf(string, "%d", i);
  8. printf("%s\n", string);
  9. double d = 123.456;
  10. sprintf(string, "%lf", d);
  11. printf("%s\n", string);
  12. return 0;
  13. }

步骤二:将字符串转换成浮点数

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. int i = 10;
  6. char string[100] = {};
  7. sprintf(string, "%d", i);
  8. printf("%s\n", string);
  9. double d = 123.456;
  10. sprintf(string, "%lf", d);
  11. printf("%s\n", string);
  12. char str[25] = "3.14";
  13. d = atof(str);
  14. printf("%lf\n", d);
  15. return 0;
  16. }

步骤三:将字符串转换成整数

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. int i = 10;
  6. char string[100] = {};
  7. sprintf(string, "%d", i);
  8. printf("%s\n", string);
  9. double d = 123.456;
  10. sprintf(string, "%lf", d);
  11. printf("%s\n", string);
  12. char str[25] = "3.14";
  13. d = atof(str);
  14. printf("%lf\n", d);
  15. int num1 = 0;
  16. char str1[25] = "100";
  17. num1 = atoi(str1);
  18. printf("%d\n", num1);
  19. return 0;
  20. }

步骤四:将字符串转换成长整数

代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. int i = 10;
  6. char string[100] = {};
  7. sprintf(string, "%d", i);
  8. printf("%s\n", string);
  9. double d = 123.456;
  10. sprintf(string, "%lf", d);
  11. printf("%s\n", string);
  12. char str[25] = "3.14";
  13. d = atof(str);
  14. printf("%lf\n", d);
  15. int num1 = 0;
  16. char str1[25] = "100";
  17. num1 = atoi(str1);
  18. printf("%d\n", num1);
  19. long num2 = 0;
  20. char str2[25] = "100000";
  21. num2 = atol(str2);
  22. printf("%ld\n", num2);
  23. return 0;
  24. }

7.4 完整代码

本案例的完整代码如下所示:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. int i = 10;
  6. char string[100] = {};
  7. sprintf(string, "%d", i);
  8. printf("%s\n", string);
  9. double d = 123.456;
  10. sprintf(string, "%lf", d);
  11. printf("%s\n", string);
  12. char str[25] = "3.14";
  13. d = atof(str);
  14. printf("%lf\n", d);
  15. int num1 = 0;
  16. char str1[25] = "100";
  17. num1 = atoi(str1);
  18. printf("%d\n", num1);
  19. long num2 = 0;
  20. char str2[25] = "100000";
  21. num2 = atol(str2);
  22. printf("%ld\n", num2);
  23. return 0;
  24. }

联合与枚举 、 高级指针 、 C语言标准库(一)的更多相关文章

  1. 附录二 C语言标准库

    上章回顾 数组和指针相同与不同 通过指针访问数组和通过数组访问指针 指针在什么时候可以加减运算 函数指针的申明和调用 函数数组和数组函数 git@github.com:Kevin-Dfg/Data-S ...

  2. C 高级编程3 静态库与动态库

    http://blog.csdn.net/Lux_Veritas/article/details/11934083http://www.cnblogs.com/catch/p/3857964.html ...

  3. GO语言标准库—命令行参数解析FLAG

    flag包是Go语言标准库提供用来解析命令行参数的包,使得开发命令行工具更为简单 常用方法 1.flag.Usage 输出使用方法,如linux下ls -h的帮助输出 2.flag.Type(参数名, ...

  4. C语言标准库 qsort bsearch 源码实现

    C语言是简洁的强大的,当然也有很多坑.C语言也是有点业界良心的,至少它实现了2个最最常用的算法:快速排序和二分查找. 我们知道,对于C语言标准库 qsort和 bsearch: a. 它是“泛型”的, ...

  5. Go语言标准库flag基本使用

    文章引用自   Go语言标准库flag基本使用 os.Args 如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数. package main import ...

  6. Go语言标准库_输入/输出

    Go语言标准库_输入/输出 转载节选自<Go语言标准库> Reader 接口 type Reader interface { Read(p []byte) (n int, err erro ...

  7. Go语言标准库之JSON编解码

    Go语言标准库之JSON编解码 基本的类型 Go语言中的数据类型和JSON的数据类型的关系 bool -> JSON boolean float64 -> JSON numbers str ...

  8. Go语言标准库之time

    Go语言标准库之time 时间的格式化和解析 格式化 Format Go语言和其他语言的时间格式化的方式不同,Go语言格式化的方式更直观,其他的语言一般是yyyy-mm-dd package main ...

  9. 《C与指针》——高级指针话题

    指针真是让人又爱又恨..... 首先还是先来看一下C语言中的高级指针声明.不要被表面迷惑最重要. /* ** <C和指针>——高级指针话题 */ int i; //定义一个整型变量 int ...

  10. C++(指针和高级指针)-上篇

    [在指针中存储地址] int *pAge=nullptr; //将PAge声明为int指针,即用于存储int变量的地址 如果将指针初始化为0或者NUll,以后必须将变量的地址赋给它,如下例代码: ; ...

随机推荐

  1. JQ基础练习---图片划过变暗

    简单分享下,划过一张图片其余图片变暗,图片划过变暗的简单效果,JQ实现主要是css写法跟思路变化. <script src="http://ajax.googleapis.com/aj ...

  2. oracle建库及plsql建表空间的用法

    所有程序—>ORACLE-JHEMR----------->配置和移植工具----->DataBase Configuration Assistant-------中间就需要改一个数 ...

  3. formvalidator4.1.3 使用过程中一些问题的解决

    在使用formvalidator4.1.3 插件时  发现 正常情况调用时没有问题的,但是我们的项目中需要把css  .js 之类的静态资源用单独的域名加载. 那么问题就来了在 该插件中 有一段这样的 ...

  4. 如何在 CentOS 中设置 NTP 服务器

    网络时间协议(NTP)用来同步网络上不同主机的系统时间.你管理的所有主机都可以和一个指定的被称为 NTP 服务器的时间服务器同步它们的时间.而另一方面,一个 NTP 服务器会将它的时间和任意公共 NT ...

  5. 简单模拟QQ界面框架。

    package com.lixu.qqjiemian; import java.util.Timer; import java.util.TimerTask; import android.app.A ...

  6. 求x^0+x^1+x^2+.......x^n mod p; x,n,p<=10^9

    方法一:快速幂.但是肯定还是超时. 方法二:利用等比数列公式,但是有除法,做不下去了. 方法三:有点分治的味道.. n为偶数时,x^0+x^1+x^2+.......x^n=(x^0+x^1+x^2+ ...

  7. struts2 ModelDriven 和 Preparable 拦截器

    Struts2 运行流程图-1

  8. IT公司100题-14-排序数组中和为给定值的两个数字

    问题描述: 输入一个升序排序的数组,给定一个目标值target,求数组的两个数a和b,a+b=target.如果有多个组合满足这个条件,输出任意一对即可. 例如,输入升序数组[1, 3, 4, 5, ...

  9. <转>2015-7-14面试题

    由于一些原因,最近打算换一份工作,主要目标是大型的互联网公司.在经历了上周三天小公司试水后,昨天终于开始正式的面试之旅了(其实接到面试通知的就几家公司

  10. 基于K2的集成供应链流程解决方案

    基于K2的集成供应链流程解决方案http://www.k2software.cn/zh-hans/scm-solution 一.详细功能模块 需求管理模块多渠道管理.需求计划.需求感知与传递市场营销及 ...