1. 字符串操作
1.1 字符串遍历
可以通过数组方式遍历字符串。
char* str="Hello World";
for(int i = 0;'\0' != str[i];++i){
printf("%c\n",str[i]);
}
也可以使用指针方式
char* str="Hello World";
for(int i = 0;'\0' != *str;++i){
printf("%c\n",*(str+i));
}
指针方式可以简化成
while('\0' != *str){
printf("%c\n",*str++);
}
1.2 字符串赋值
char* s = "Hello World";
char* t;
t = s;
printf("%s\n",t);
没有产生新的字符串,只是s和t指向相同的字符串。下面是查看两个字符串的地址。
2.字符串字面量初始化
字符串字面量初始化字符数组
字符串字面量初始化字符串指针
char* str1 = "Hello World";
char str2[] = "Hello World";
str1[5] = '\0'; // Error
str2[5] = '\0'; // OK
printf("str1=%s\n",str1);
printf("str2=%s\n",str2);
str1
是一个指针,初始化指向一个字符串常量。(在C99标准中,str1
报警告,提示应该使用const char*)
修改字符串常量可能会导致严重后果。
str2
是一个字符数组,初始化把字符串字面量自动复制到数组中。
- 如果需要构造字符串使用数组;如果需要处理字符串使用指针。
- 字符串不需要修改使用字符串字面量初始化字符串指针。
- 字符串需要修改使用字符串字面量初始化字符数组。
3.字符串函数
stdio.h
- sprintf:数据按格式写入字符串
- sscanf:按格式从字符串读出数据
stdlib.h
- atof:字符串转浮点数
- atoi:字符串转整数
- atol:字符串转长整数
string.h
- strcpy:字符串拷贝
- strncpy:指定个数字符串拷贝
- strcat:字符串连接
- strncat:指定个数字符串连接
- strcmp:字符串比较
- strncmp:指定个数字符串比较
- strchr:查找字符串中第一个出现指定字符的位置
- strrchr:查找字符串中最后一个出现指定字符的位置
- strstr:查找字符串中第一个出现指定子串的位置
- strtok:切分字符串
- strerror:获取出错信息
- strlen:获取字符串长度
4. 字符串数组与字符串指针数组
4.1 字符串数组
字符串数组,可以看成二维字符数组,只是初始化可以使用字符串方式。
char arr[12][10] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
4.2 字符串指针数组
char* arr[12] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
4.3 字符串数组与字符串指针数组的区别
- 大小的区别
char arr1[][10] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
char* arr2[] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
printf("sizeof(arr1)=%d\n",sizeof(arr1));
printf("sizeof(arr2)=%d\n",sizeof(arr2));
2.二维指针的区别
#include <stdio.h>
int main () {
char arr1[][10] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
char* arr2[] = {"January","February","March","April",
"May","June","July","August",
"September","October","November","December"};
char** p1 = arr1;
for(int i=0;i<12;++i){
printf("%s\n",p1[i]);
}
char** p2 = arr2;
for(int i=0;i<12;++i){
printf("%s\n",p2[i]);
}
return 0;
}
实践
- 已知十天干和十二地支
天干:甲、乙、丙、丁、戊、己、庚、辛、壬、癸
地支:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥
按顺序打印出六十甲子
甲子、乙丑、丙寅、丁卯、戊辰、己巳、庚午、辛未、壬申、癸酉、
甲戌、乙亥、丙子、丁丑、戊寅、己卯、庚辰、辛巳、壬午、癸未、
甲申、乙酉、丙戌、丁亥、戊子、己丑、庚寅、辛卯、壬辰、癸巳、
甲午、乙未、丙申、丁酉、戊戌、己亥、庚子、辛丑、壬寅、癸卯、
甲辰、乙巳、丙午、丁未、戊申、己酉、庚戌、辛亥、壬子、癸丑、
甲寅、乙卯、丙辰、丁巳、戊午、己未、庚申、辛酉、壬戌、癸亥
已知今年的纪年,输入21世纪任意年份,打印出对应的甲子。
已知今年的纪年,打印出21世纪所有年份的甲子。
已知小明同学的属相,推断出可能的年龄。
#include <stdio.h>
#include <stdbool.h>
main(){
char* tiangan ="甲乙丙丁戊己庚辛壬癸";
char* dizhi = "子丑寅卯辰巳午未申酉戌亥";
for(int i=0,j=0;i<10 && j<12 ;++i,++j){
printf("%.3s%.3s ",tiangan+i*3,dizhi+j*3);
if(i==9 && j!=11){
i=-1;
printf("\n");
}
if(i!=9 && j==11){
j=-1;
}
}
printf("\n");
char arr[60][7]= {0};
for(int i=0;i<60;++i){
sprintf(arr[i],"%.3s%.3s",tiangan+i%10*3,dizhi+i%12*3);
}
for(int i=0;i<60;++i){
printf("%s ",arr[i]);
if((i+1)%10 == 0) printf("\n");
}
int start = 2019 - 35;
// printf("%s",arr[2019-start]);
printf("请输入年份:");
int y;
scanf("%d",&y);
printf("%d是%s年\n",y,arr[(y-start)%60]);
}
9. main()
参数与返回值
9.1 main()
参数
main()的完全形式是这样的。
int main(int argc,char* argv[])
或者
int main(int argc,char** argv)
其中,argc是命令与参数数量。argv是命令和参数组成的字符串数组。argv[0]是命令本身。其余是参数。
int main(int argc,char* argv[]){
for(int i=0;i<argc;++i){
printf("%d:%s",i,argv[i]);
}
return 0;
}
9.2 main()
返回值
main()
返回值是与调用程序交互的,返回程序执行状态。通常0表示执行成功,非零表示执行失败。
int main(){
int n;
printf("请输入一个整数:");
scanf("%d",&n);
return n;
}