33深入理解C指针之---通过字符串传递数据
一、传递字符串:在函数的参数列表中,将参数声明为char指针即可实现通过字符串传递参数
1、特征:
1)、字符串以char指针的形式传递,一般是const指针传递;
2)、使用字符数组声明字符串,调用字符串时直接使用数组名称即可;
3)、使用字符数组声明字符串,调用字符串时直接在数组名前加&即可;
4)、使用字符数组声明字符串,调用字符串时直接使用数组首元素地址即可;
5)、使用字符指针声明字符串,调用字符串时直接使用指针即可;
2、传递简单字符串:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 size_t stringLength(char *string){ 6 size_t length = 0; 7 while(*(string++)){ 8 length++; 9 } 10 11 return length; 12 } 13 14 int main(int argc, char **argv) 15 { 16 char simpleArr[] = "Simple String!"; 17 char *ptrSimpleArr = (char *)malloc(strlen("Simple String!") + 1); 18 strcpy(ptrSimpleArr, "Simple String!"); 19
20 printf("使用数组名获取字符串:%s and %d\n", simpleArr, stringLength(simpleArr)); 21 printf("使用数组名加&获取字符串:%s and %d\n", &simpleArr, stringLength(&simpleArr)); 22 printf("使用数组首元素地址获取字符串:%s and %d\n", &simpleArr[0], stringLength(&simpleArr[0])); 23 printf("使用指针获取字符串:%s and %d\n", ptrSimpleArr, stringLength(ptrSimpleArr));
24
25 return 0;
26 }
代码说明:
1)、第16行代码是字符串的字符数组声明法
2)、第20行代码是使用数组名获取字符串
3)、第21行代码是使用数组名加&获取字符串
4)、第22行代码是使用数组首元素地址获取字符串
5)、第17行代码是字符串的字符指针声明法
6)、第22行代码是使用指针获取字符串
7)、stringLength函数实现了类似strlen函数的作用,返回制定字符串长度
3、传递字符常量的指针:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 size_t stringLength(const char *string){ 6 size_t length = 0; 7 while(*(string++)){ 8 length++; 9 } 10 11 return length; 12 } 13 14 int main(int argc, char **argv) 15 { 16 char simpleArr[] = "Simple String!"; 17 char *ptrSimpleArr = (char *)malloc(strlen("Simple String!") + 1); 18 strcpy(ptrSimpleArr, "Simple String!"); 19 20 printf("使用数组名获取字符串:%s and %d\n", simpleArr, stringLength(simpleArr)); 21 printf("使用数组名加&获取字符串:%s and %d\n", &simpleArr, stringLength(&simpleArr)); 22 printf("使用数组首元素地址获取字符串:%s and %d\n", &simpleArr[0], stringLength(&simpleArr[0])); 23 printf("使用指针获取字符串:%s and %d\n", ptrSimpleArr, stringLength(ptrSimpleArr)); 24 25 return 0; 26 }
代码说明:
1)、stringLength函数实现了类似strlen函数的作用,返回制定字符串长度,传入的是const的char指针,防止字符串被意外修改
4、传递需要初始化的字符串:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 size_t stringLength(const char *string){ 6 size_t length = 0; 7 while(*(string++)){ 8 length++; 9 } 10 11 return length; 12 } 13 14 size_t longInt(int i){ 15 int tmp = 1; 16 while(i / 10){ 17 i = i / 10; 18 tmp++; 19 } 20 21 return tmp; 22 } 23 24 char *format(char *buffer, size_t size, const char *name, size_t quantity, size_t weight){ 25 snprintf(buffer, size, "Item: %s Quantity: %u Weight: %u", name, quantity, weight); 26 27 return buffer; 28 } 29 30 char *formata(char *buffer, size_t size, const char *name, size_t quantity, size_t weight){ 31 char *formatString = "Item: %s Quantity: %u Weight: %u"; 32 //size_t formatStringLength = strlen(*formatString) - 6; 33 size_t formatStringLength = strlen( "Item: %s Quantity: %u Weight: %u") - 6; 34 size_t nameLength = strlen(name); 35 size_t quantityN = longInt(quantity); 36 size_t weightN = longInt(weight); 37 size_t length = formatStringLength + nameLength + quantityN + weightN + 1; 38 39 if(buffer == NULL){ 40 buffer = (char *)malloc(length); 41 size = length; 42 } 43 44 snprintf(buffer, size, formatString, name, quantity, weight); 45 46 return buffer; 47 } 48 49 typedef struct forM{ 50 char form1[34]; 51 char name[10]; 52 int quantity; 53 int weight; 54 int size; 55 } ForM; 56 57 int main(int argc, char **argv) 58 { 59 ForM forM1; 60 char *form2 = "Item: %s Quantity: %u Weight: %u"; 61 strcpy(forM1.form1, form2); 62 strcpy(forM1.name, "Axle"); 63 forM1.quantity = 205; 64 forM1.weight = 40005; 65 size_t size1 = stringLength(form2) + strlen(forM1.name) + longInt(forM1.quantity) + longInt(forM1.weight) - 5; 66 printf("%s\n", format(forM1.form1, forM1.size, forM1.name, forM1.quantity, forM1.weight)); 67 68 ForM forM2; 69 strcpy(forM2.name, "Axileguo"); 70 forM2.quantity = 2500; 71 forM2.weight = 450; 72 size_t size2 = stringLength(form2) + strlen(forM2.name) + longInt(forM2.quantity) + longInt(forM2.weight) - 5; 73 printf("%s\n", format(forM2.form1, forM2.size, forM2.name, forM2.quantity, forM2.weight)); 74 75 return 0; 76 }
代码说明:
1)、通过引入结构体,使的编程思路更加清晰。
写代码的一些技巧:
1 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 2 * 作者代号: *** :guochaoxxl 3 * 版权声明: *** :(魎魍魅魑)GPL3 4 * 联络信箱: *** :guochaoxxl@gmail.com 5 * 文档用途: *** :深入理解C指针 6 * 文档信息: *** :~/WORKM/StudyCode/CodeStudy/cnblogs_understanding_and_using_c_pointers/chapter5/testc11.c 7 * 修订时间: *** :2017年第41周 10月09日 星期一 上午08:58 (282天) 8 * 代码说明: *** :自行添加 9 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ 10 #include <stdio.h> 11 #include <string.h> 12 #include <stdlib.h> 13 14 char *returnALiteral1(int code){ 15 switch(code){ 16 case 100: 17 return "Boston Processing Center!"; 18 break; 19 20 case 200: 21 return "Denver Processing Center!"; 22 break; 23 24 case 300: 25 return "Atlanta Processing Center!"; 26 break; 27 28 case 400: 29 return "San Francisco Processing Center!"; 30 break; 31 32 default: 33 printf("Error!"); 34 return "None!"; 35 } 36 } 37 38 char *returnALiteral2(int code){ 39 char *str = (char *)malloc(sizeof(char) * 50); 40 41 switch(code){ 42 case 100: 43 strcpy(str, "Boston Processing Center!"); 44 break; 45 46 case 200: 47 strcpy(str, "Denver Processing Center!"); 48 break; 49 50 case 300: 51 strcpy(str, "Atlanta Processing Center!"); 52 break; 53 54 case 400: 55 strcpy(str, "San Francisco Processing Center!"); 56 break; 57 58 default: 59 printf("Error!"); 60 strcpy(str, "None!"); 61 } 62 63 return str; 64 } 65 66 int main(int argc, char **argv) 67 { 68 int code; 69 printf("please input the code: "); 70 scanf("%d", &code); 71 printf("you input the code: %d\n", code); 72 printf("the result: %s\n", returnALiteral1(code)); 73 74 printf("please input the code: "); 75 scanf("%d", &code); 76 printf("you input the code: %d\n", code); 77 printf("the result: %s\n", returnALiteral2(code)); 78 79 return 0; 80 }
代码说明:
1)、函数returnALiteral1的实现中,主要通过函数返回字符串常量,每一步都需要返回
2)、函数returnALiteral2的实现中,主要通过函数返回字符指针,最后统一返回
3)、函数returnALiteral2的实现中,切记需要先分配内存
4)、建议使用函数returnALiteral2的实现方式
5)、两个函数的实现不同,但是结果是相同的