【字符串回顾】

1、定义字符串的方法:
① 字符串常量:双引号里的字符+编译器自动提供结束标志\0字符,作为一个字符串被存储在内存里。
字符串常量属于【静态存储(static storage)类】,静态存储是指如果一个函数中使用字符串常量,即使是多次调用这个函数,该字符串在程序的整个运行过程中只存储一份。
整个引号中的内容作为指向该字符串存储位置的指针。
printf("%s, %p, %c\n", "we", "we", *"we");
%s格式输出字符串
%p格式输出字符串第一个字符的地址
*"we"产生所指向地址中的值,即字符串"we"中第一个字符
② 字符数组
const char ml[12] = "HelloWorld";
const char ml[] = {
'H','e','l','l','o','W','o','r','l','d','\0'
};
注意
(1)如果没有结束标志的空字符'\0',得到的只是一个字符数组而不是一个字符串。
(2)指定数组大小时,一定要确保数组元素比字符串长度至少多1,多出来的1个元素用于容纳空字符,未被使用的元素均被自动初始化为'\0'

3、字符数组名也是数组首元素的地址,可以使用指针符号建立字符串:
const char *m3[] = "HelloWorld";

4、数组形式和指针形式的不同?

数组形式:

    在计算机内存中被分配一个11个元素的数组,包括一个'\0';每个元素都被初始化为相应的字符

    被引用的字符串存储在【可执行文件的数据段】部分;当程序被加载到内存中时,字符串也被加载到内存中。

    被引用的字符串被称为【位于静态存储区】。

    但是在程序开始运行后才为数组分配存储空间。这时把被引用的字符串复制到数组中。此后,编译器会把数组名m3看作【数组首元素】。【注意】在数组形式中,m3是个【地址常量】,更改m3意味着更改数组存储的地址。可以用m3+1标识数组里的下一个元素,但不能使用m3++;因为增量运算符只能用在变量名前,不能用在常量前。
 

指针形式:

在静态存储区为字符串预留38个元素的空间。一旦程序开始执行,还要为【指针变量m3】另外【预留一个存储位置】,以在该指针变量中存储字符串的地址。

指针变量初始时指向字符串第一个字符,++m3将指向第二个字符。

数组初始化是从静态存储区把一个字符串复制给数组,指针初始化只是复制字符串的地址。

【建议】初始化一个指向字符串文字的指针时使用const修饰符。

③ 字符串数组

(1)

const char *mytal[5] = {
				"Adding members swiftly",
				"String2",
				"String3",
				"String4",
				"String5"
			}
mytal是一个由5个【指向char的指针】组成的数组,数组每一个元素都是一个char类型值的【地址】,每一个地址指向相应字符串的【第一个字符】。即:*mytal[0]=='A'.
mytal数组实际只是存放【字符串的地址】,字符串存在【程序用来存放常量的那部分内存】中。
(2) 建立一个二维数组。
【注意】与指针数组的区别:指针数组建立的是一个不规则数组,每一行长度由初始化字符串决定。这个不规则数组不浪费任何存储空间。
    mytal是一个指向char的指针的数组,二维数组是一个char数组的数组。即指针数组存放5个地址,二维数组存放5个完整的字符数组
6、
char * mesg = "String1";
char * copy;
copy = mesg;<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">   </span>
   从输出信息可以看出,mseg和copy两个指针分别存放在不同的内存单元(【指针的地址】不同),而【指针的值】是该指针中存放的地址,且存放相同的值(地址)。
   上述代码的功能是产生【指向同一个字符串】的【第二个指针】。

7、如果想把一个字符串读到程序中,必须首先建立一个空间以存放读入的字符串。
char * name;
scanf("%s", name);
上述代码可能会导致name覆盖程序中的数据和代码从而导致异常中止。因为scanf()把信息【复制】到由参数给定的【地址】中,而在这种情况下,参数是个未初始化的指针,name可能指向任何地方。

8、strcat与strncat
char* strcat(char *, char *);
将第二个字符串的一份拷贝添加到第一个字符串的末尾,从而使第一个字符串成为一个新的组合字符串,第二个字符串没有改变。
返回值:char*(指向char的指针)类型。返回它的第一个参数的值,即【其后添加了第二个字符串的那个字符串中第一个字符的地址】。

strncat(str1, str2, 10); // 把str2字符串中的内容添加到str1上,直到【添加到10个字符】或【遇到空字符】为止。
增加了一个参数指明最多允许添加的字符数目。

strcat()函数并不检查第一个数组是否能容纳第二个字符串,如果没有为第一个数组分配足够大的空间,多出来的字符溢出到相邻存储单元时会出现问题。

9、strcmp与strncmp
char str1 = "String1";
char try[20];
gets(try);
(try != str1)检查的是两个字符串的地址是否一样,由于str1与try被存放在不同的位置,故try==str1永远不会成立。
strcmp(str1, str2)函数比较的是【字符串内容】而不是字符串地址。
返回值:  ANSI标准规定,若第一个字符串在字母表的顺序先于第二个字符串,则strcmp(str1, str2) < 0; str1-str2<0
若第一个字符串在字母表的顺序后于第二个字符串,则strcmp(str1, str2) > 0; str1-str2>0
若两个字符串相同,返回0;
strncmp(str1, str2, n) 比较字符串时,可以比较到字符串不同处,也可以比较完【由第三个参数指定的字符数】

10、strcpy与strncpy
strcpy(str1, str2):把字符串从str2里复制到str1。等价于赋值运算符。
strncpy(target, source, n):从source把n个字符(空字符之前的字符,由二者中最先满足的那个决定终止)复制到target中。

11、sprintf()函数
头文件:stdio.h
功能:获取输入,并把输入格式化为标准形式后存放在字符串中(而不是写到输出显示)。
注意:sprintf()的第一个参数是目标字符串的地址,其余参数与printf()一样。即使用sprintf()和使用printf()的方法一样,只是结果字符串被【存放在目标字符串】中,而不是被显示在屏幕上。

12、Others
=================================================================================================================================
补充:
1、字符串(常量)与字符(常量)("x"与'x')
'x'  属于基本类型,
"x" 属于派生类型,实际上由两个字符'x'和'\0'组成
2、
%a/%A
%c
%s
%p 指针
%d/%i 有符号十进制
%u 无符号十进制
%o 无符号八进制
%x/%X 无符号十六进制
%e/%E 浮点数
%f 浮点数
%g/%G
%% 一个%
3、printf()
① 转换说明修饰符
printf("%04d", 1); // 0001
printf("%.04d", 1);// 0001
printf("%20s", "s");  // 右对齐输出字符串s,
printf("%-20s", "s"); // 左对齐
printf("%6.2lf", 1.5); // 右对齐输出  '  1.50'(总长6,保留小数点后2位)
printf("%+6.2lf", 1.5); // 右对齐输出 ' +1.50'(总长6,保留小数点后2位,输出+)
printf("%06.2lf", -1.5); //前导0,输出'-01.50'
printf("% 6.2lf", -1.5); //前导空格,输出'-01.50'

printf("%-24.5s", "ABCDEFGHIJKLMN"); 字符串左对齐(+右对齐),长度24,只输出前5个字符
② 【重要】参数传递机制在系统中的工作原理

【引入】

【原理分析】



4、scanf()
① 转换说明修饰符
scanf("%*d%*d%d", &n); // 使函数跳过相应的输入项目。
scanf("%10s", str);         // 最大字段宽度,在达到最大字段宽度或者遇到第一个空白字符时,停止对输入项的读取
scanf()函数读取输入字符时,它跳过空白字符直到遇到一个非空白字符。

5、【重要】printf与scanf的*修饰符
①printf();
功能:实现【不指定字段宽度】,而是希望由程序来指定该值,那么可以在字段宽度部分使用*代替数字来达到目的,但是也必须使用给一个参数来告诉函数字段宽度应该是什么。即如果转换说明符是%*d,那么参数列表中应该包括【一个*的值】和【一个d的值】。
printf("The width is %*d: \n", width, number);
printf("The width is %*.*lf: \n", width, precision, number);
②scanf("");
功能:使函数跳过相应的输入项目。
scanf("%*d%*d%d", &n); // 跳过两个整数,并把第三个整数赋值给n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值