C语言 第八章 指针(下)

第八章 指针(下)

指针变量做函数参数

如果要改变a, b的值,要使用指针指向a,b

输入两个数,如果第一个数大于第二个数,则交换两个数,否则直接输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
int a,b;
printf("请输入两个数字\n");
scanf("%d%d", &a, &b);
if(a<b) swap(&a, &b);
printf("%d, %d\n", a, b);
return 0;
}

void swap(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}

数组函数参数

1
2
3
4
5
6
7
8
int a[] == int *a;
int a[N] == int *a;

int a[N][4] = int (*a)[4];
int a[][4] = int (*a)[4];

int *a[N] == int *a;
int *a[] == int *a;
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
double d[3] = {1.1, 2.2, 4.3};
fun_add(d);
printf("%f\n", d[2]);
}

void fun_add(double *p)
{
p[1] = p[0] + p[2];
// 上面一行代码与下一行相同
//*(p+1) = *p + *(p+2);
}

函数的指针

字符串的指针

字符串结尾会有\0来标识当前字符串的结束

初值个数不得超过数组大小

1
char ch[20] = "HelloWorld";

以char *型指针变量保存字符串首地址

1
2
3
4
5
6
7
8
9
char *ps = "iPhone";
// 只是将ps的指向地址改变,而不保存字符串内容本身。
ps = "iPad";

char s[] = "iTouch";
// 可以
ps = s;
// 错误,s的值不可以改变
s = "iMac";

字符串的输入输出

printf(“%s”, 一级地址);

其含义时从改地址开始逐个字符输出,直到遇到'\0'为止(\0不输出,也不自动换行)

输出字符串其他略有不同,后面要接地址,而不是直接接数据

1
2
3
4
printf("%d", 数据);
printf("%c", 数据);
printf("%f", 数据);
printf("%s", 地址);

puts(一级地址)

其含义是从地址开始逐个字符输出,直至\0为止(\0不输出);然后自动换行(即最后再多输出一个'\n'

1
2
3
puts(ps);
// 相当于
printf("%s\n", ps);

scanf(“%s”, 一级地址)

其含义是:读入键盘键入的一个字符串(最后要键入回车表示结束,但不键入’\0’),存入“一级地址”开始的一顿内存空间(回车符不存入),并自动在最后一个字符的后面添加'\0'

如果字符串中含有空格或Tab符,只能读入空格或Tab符之前的部分(不读空格和Tab符)。

1
2
3
4
5
char a[30];
scanf("%s", a);
printf("%s", a);
// 此时输入 how are you? <回车>
// 只会输出 how

gets(一级地址)

其含义是:读入从键盘键入的一行字符(最后一定要键入回车表示结束,但不键入'\0',存入“一级地址”开始的一顿内存空间(回车符不存入),并自动在最后一个字符的后面添加'\0'。如果字符串中含有空格、Tab符也一起读入并不中断。)

1
2
3
4
5
char b[30];
scanf("%s", b);
printf("%s", b);
// 此时输入 how are you? <回车>
// 会整句输出

字符串处理(常用套路)

数组法

1
2
3
4
5
6
7
// 第一种
for(i=0; s[i]!='\0'; i++)
printf(s[i]);

// 或者
for(i=0; s[i];i++)
printf(s[i]);

指针法

1
2
3
4
5
6
7
char *p;
p = 字符串起始地址;
while(*p != '\0')
{
用*p访问或处理每个字符;
p++; //使p指向字符串的下一个字符
}

'\0'和末尾字符定位

让p指向字符串的最后一个字符

1
2
3
while(*p)
p++;
p--;

字符串的连接

1
2
3
4
5
6
7
8
9
10
11
12
13
char s1[20] = "Hello";
char s2[] = "World";
char *ps1 = s1;
while(*ps1) ps1++;

char *ps2 = s2;
while(*ps2)
{
*ps1 = *ps2;
ps1++;
ps2++;
}
*ps1='\0';

字符串倒序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void reverse(char *s)
{
char *p, *q, t;

while(*q) q--;

while(*p)
{
t = *q;
*q = *p;
*p = t;
p++;q++;
}
}

int main()
{
char st[80];
scanf("%s", st);
printf("正序: %s", st);
reverse(st);
printf("倒序: %s", st);
}

常用字符串函数

使用以下函数要包含头文件 #include <string.h>

函数含义功能详细说明
strlen(地址)求字符串长度函数返回值为字符串的长度,即从地址开始到’\0’的字符个数(不计’\0’,但其中空格、Tab符、回车符等都计数)
strcat(串1地址, 串2地址)字符串连接 “串1=串1+串2”把从串2地址开始到’\0’的内容,连接到串1的后面(删去串1最后的’\0’),结果仍存入串1地址开始的空间中,并在结果字符串末尾自动添加新’\0’(串1地址的空间应足够大)
strcpy(串1地址, 串2地址)字符串拷贝 “串1=串2”把从串2地址开始到’\0’的内容,拷贝到串1地址开始的空间中,’\0’也一同拷贝(串1地址的空间应足够大)
strcmp(串1地址, 串2地址)字符串比较 “串1>串2” “串1<串2” “串1==串2”两个字符串的大小结果由函数返回值说明: 若函数返回值 > 0,说明 串1 > 串2 若函数返回值 < 0,说明 串1 < 串2 若函数返回值 == 0,说明 串1 = = 串2

sizeof

求占用多少字节,结果为整数

sizeof 是运算符,不是函数,同时也是关键字

sizeof(类型 或表达式)

常用字符函数

需要包含头文件 #include <ctype.h>

isalpha(ch)检查ch是否为字母字符,是返回1,否返回0
isdigit(ch)检查ch是否为数字字符,是返回1,否返回0
isspace(ch)检查ch是否为空白分隔符,即是否为空格、跳格(Tab, ‘\t’)、换行符(‘\n’)、回车符(‘\r’)、换页符(‘\f’)5种之一。 如是这些字符返回1,否则返回0
islower(ch)检查ch是否为小写字母字符,是返回1,否返回0
isupper(ch)检查ch是否为大写字母字符,是返回1,否返回0
tolower(ch)将ch转换为小写字母,函数返回转换后的字符
toupper(ch)将ch转换为大写字母,函数返回转换后的字符