一、指针
1.一级指针:
通常用作函数的输入参数,因为一级指针作为函数参数,在调用的时候,实参和形参是不同的内存空间,只是,这个内存空间存放的指针指向的是同一块地址 ,所以形参在函数执行中可以访问实参指向的内存空间,但是形参的指向的改变并不能影响实参。
一级指针做函数参数, 在函数内做形参做重新指向并 不会影响实参的指向。
//一级指针的应用
void Swap(int* p,int* q)
{
int temp = *p; //a
*p = *q;
*q = temp;
}
int main()
{
int a = 10;
int b = 20;
Swap(&a, &b); // 栈帧 开辟 回退问题 -> 函数调用
printf("交换后的值:%d %d\n", a, b);
}
2.指针和数组的关系
int CicleNum(int* arr,int len)
{
assert(arr != NULL);
int left = len;// 剩余的人数
int count = 0;// 报数 NUM 退出
int res = -1;// 返回剩余一个人的编号
for (int i = 0;left > 1; i = ++i % len)
{
if (*(arr+i) != -1) { //arr[i]
count++;
}
if (count == NUM) { // 报数为NUM的人退出
*(arr + i) = -1;
count = 0;
left--;
}
}
for (int i = 0; i < len; i++) {
if (*(arr + i) != -1) {
res = *(arr + i);//arr[i]
}
}
return res;
}
int main()
{
Money(85);
int arr[] = {1,2,3,4,5,6,7,8,9,10};
printf("%d ",CicleNum(arr, 10));
}
数组和指针关系:(p+i) <==> &p[i]
const char *str = "hello";
*(str+i) = 'z';//error
*(str+i) -> str[i]
char arr[] = "hello";
* arr[0] = 'z';//right
数组arr[]在 CicleNum()中退化为指针*arr
(1)数组:数组是用于储存多个相同类型数据的集合。
(2)指针:指针相当于一个变量,但是它和不同变量不一样,它存放的是其它变量在内存中的地址
区别:
1)同类型指针变量可以相互赋值,数组不行,只能一个一个元素的赋值或拷贝;
2)数组在内存中是连续存放的,开辟一块连续的内存空间。数组是根据数组的下进行访问的,多维数组在内存中是按照一维数组存储的,只是在逻辑上是多维的;
3)指针可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内存。
3.const和指针结合
1. 指针 和 const的使用
1)
int a = 10;
int b = 20;
const int* p = &a; -> 不能修改指向变量的值
*p = 100;//error
p = &b; //right
*p = 200;//error
2)
int a = 10,b=20;
int* const p = &a;
-> 修饰指针变量本身。一经指向a,不能指向其他地址。
没有限定a本身的值是否被修改
p = &b;//error
*p = 100;//right
3)
const int a = 10; // a常变量
int* p = &a; //error *p = 10; error
const int* p = &a;//right
4)
const int* const p = &a; // p指向a,不能指向其他变量。p不能修改a的值
4.字符串的定义和特点
1) char ch[] = "hello"; //"hello"以字符数组的形式存储 数组大小5+1 '\0'
2) char *p = "hello"; //字符串常量"hello" //error
const char* str = "hello"; //right
3)char str[5];
scanf(“%s”,str);
4)char str[5];gets(str);
5.字符串相关的操作
strcpy(p, p1) 复制字符串
strncpy(p, p1, n) 复制指定长度字符串
strcat(p, p1) 附加字符串
strncat(p, p1, n) 附加指定长度字符串
strlen(p) 取字符串长度
strcmp(p, p1) 比较字符串
strcasecmp忽略大小写比较字符串
strncmp(p, p1, n) 比较指定长度字符串
strchr(p, c) 在字符串中查找指定字符
strrchr(p, c) 在字符串中反向查找
strstr(p, p1) 查找字符串
strpbrk(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找该集合的任一元素
strspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找不属于该集合的任一元素的偏移
strcspn(p, p1) 以目标字符串的所有字符作为集合,在当前字符串查找属于该集合的任一元素的偏移
* 具有指定长度的字符串处理函数在已处理的字符串之后填补零结尾符
(1)strlen(p) 取字符串长度
字符串基本认识
int main()
{
char ch[] = {'h','e','l','l','o'}; //5
char arr[] = "he\0llo"; //7 字符串'\0' 结尾标记
arr[0] = 's';
int len_ch = sizeof(ch) / sizeof(ch[0]);
int len_arr = sizeof(arr) / sizeof(arr[0]);
int len_string = strlen(arr); //第一个'\0'前面字符个数
//2个
printf("ch:%d arr:%d 字符串长度%d\n",len_ch,len_arr,len_string);
return 0;
char arr[] = {'h','e','l','l','o'};
* arr -> sizeof(arr)/sizeof(arr[0]); //5
* strlen(arr); //5
(2)strcmp(p, p1) 比较字符串
strcmp(const char*str1,const char*str2); //比较大小功能
// 方法一: 采用数组形式操作 -》 需要优化
int my_strcmp1(const char* str1,const char* str2) {
assert(str1!=NULL && str2 != NULL);
int len = strlen(str1);
for (int i = 0; i <= len; i++) {
if (str1[i] == str2[i]) {
continue;
}
else if (str1[i] > str2[i]) {
return 1;
}
else {
return -1;
}
}
return 0;
}
int my_strcmp1(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
int result = 0;
int len = strlen(str1);
for (int i = 0;i <= len ; i++) {
if (str1[i] == str2[i]) {
continue;
}
else {
result = str1[i] > str2[i] ? 1 : -1;
break;
}
}
return 0;
}
//方法二:指针形式操作:
int my_strcmp1(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
int i = 0;
while (*str1 == *str2) { //abc abc
if (*str1 == '\0' && *str2 == '\0') {
return 0;
}
str1++;
str2++;
}
return *str1 > *str2 ? 1 : -1;
}
int main()
{
const char* str1 = "abc";
const char* str2 = "abg";
int num = my_strcmp1(str1,str2);
printf("%d",num);
return 0;
}
(3)tstrcat(p, p1) 附加字符串(连接字符串)
char* my_strcat(char* str1, const char* str2) {
assert(str1!=NULL && str2!=NULL);
int len = strlen(str1);
// 给str1后连接str2数据
int i = 0;
for (;i < strlen(str2); i++) {
str1[len+i] = str2[i];
}
str1[len+i] = '\0'; // 字符串结尾标记'\0'
return str1;
}
int main()
{
char ch[10] = "abc";//'\0'
char *res = my_strcat(ch, "def"); //abcdef
strcat(char*str1,const char*str2)
printf("%s",res);
return 0;
}
(4)strcpy(p, p1) 复制字符串
char* my_strcpy(char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
//指针实现方式:
while (*str2!='\0') { //abc\0 abc
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return str1;
int main()
{
char str1[10] = "abc";
const char* str2 = "defghi";
char* res = my_strcpy(str1, str2);
printf("%s",res);