一.一级指针
指针:地址的别名。
1.指针变量(即为 地址变量):
定义一个指针变量:int a = 10; int* p = &a; //注释.指针的类型必须和变量的类型相同。
例如: int a = 10 ; double* p = &a; //error 则错误。
2.元素访问:解引用(即为 间接访问符): *p
例如: int a = 10 ; int* p = &a ; *p = 100 ; //即为 将100赋值给变量a。
注释1 : 1). 类型+* -> 定义一个指针变量。
2). *+变量名 -> 解引用。
3). 1*2 -> 乘。
注释2: printf("%d",*p); //用来输出变量的值 整型数字。
例如:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
int main()
{
int a = 10;
int b = 20;
int* p1 = &a; //定义指针变量
int* p2 = &b; //定义指针变量
printf("%d %d\n", *p1,*p2); //打印 整型变量a和b的值
*p1 = *p1 + 50; //解引用 将a赋值为60
printf("%d\n", *p1);
*p2 = *p2 * 3; //解引用 将b赋值为60
printf("%d\n", *p2);
int c = 0;
c = *p1 * *p2;
printf("%d\n", c);
printf("%d %d %d\n",a,b,c);
return 0;
}
运行结果:
扩充:二级指针的基础引入。
int main()
{
int a = 10;
int b = 20;
int* p = &a ;
*p = 100 ; //解引用 给a赋值为10
p = &b;
*p = 200; //解引用 给b赋值为200
int** pp = &p;
** pp=1000;//给b赋值为1000 两次解引用
* pp = &a; //二级转一级,a的地址
* *pp = 99 ; //给a赋值为99 一次解引用
* pp=&b;
}
二.指针和数组的关系。
1.arr代表了数组首元素的地址。那么数组名+1 代表 加了一个单元格(与数据类型有 关) arr+i<=>&arr[i]
*(arr+1) <=> arr[1]
*arr <=> arr[0]
例如:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<string>
#include<assert.h>
void Move_Right_M(int *arr ,int len,int m)
{
assert(arr != NULL&&m<=len&&m>=0);
for (int i = 0; i < m; i++)
{
int temp = arr[len - m+i];//保存前移的数据
for (int j = len - m+i; j > i; j--)
{
arr[j] = arr[j - 1];
}
arr[i] = temp;
}
}
int main()
{
int arr[10] ;
printf("请输入有效个数:\n");
int n;
scanf("%d", &n);
int m;
printf("请输入数据:\n");
for (int i = 0; i < n; i++)
{
scanf("%d", arr+i); //scanf("%d",&arr[i]);
}
printf("请输入要移动的数据个数:\n");
scanf("%d", &m);
Move_Right_M(arr, n, m);
for (int i = 0; i < n; i++)
{
printf("%2d", arr[i]);
}
return 0;
}
运行结果:
扩充:
悬挂指针:野指针 int* p; 不可解引用。 并且 空指针也不可解引用 :int* p=NULL;
断言assert(p!=NULL&&len>=0); 需要引入头文件 #include<assert.h>
注释:断言在debug模式有效 在发布模式即release模式下无效。
此时则需要:
if(p==NULL||len<0)
{
exit(EXIT_FAILURE); //exit 的头文件为#include<stdlib.h>
}
三.const和指针结合。
1. const int* p=&a; 此时不能改变指向的目标的值了,但是可以更改指向目标
2. int* const p=&a; 此时可以改变指向的目标的值,但是不能更改指向目标了。
例如:
1).
int a=10;
int b=20;
const int*p=&a;
*p=100; //error
p=&b; //right
*p=200; //error
2).
int a=10;
int b=20;
int* const p=&a;
*p=100; //right
p=&b; //error
*p=200; //right
3).
const int a=10; //a常变量
int *p=&a; //error *p=100; error
const int* p=&a; //right
4).
const int * const p=&a; //p指向a,不能指向其他变量,并且p不能修改a的值。
四.字符串定义 、特点
字符串的定义。
1)char ch[]="hello";数组大小为5+1=6
2)const char* p="hello"; //无法改变hello本身 //必须给char*前面+const
*(str+i)='z' //error //所以用指针定义字符串 不能改变字符串的数据
五.字符串相关操作。
1) 字符串拷贝
方法一:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<assert.h>
#include<string.h>
char* my_strcpy(char* str1, const char* str2)
{
assert(str1 != NULL && str2 != NULL);
int len = strlen(str1);
int i = 0;
for (i; i < len; i++)
{
str1[i] = str2[i];
}
str1[i] = '\0';
return str1;
}
int main()
{
char str1[10] = "abc";
const char* str2 = "defghi";
char* res = my_strcpy(str1,str2 );
printf("%s", res);
return 0;
}
方法二:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<assert.h>
char* my_strcpy(char* str1, const char* str2)
{
assert(str1 != NULL && str2 != NULL);
while (*str2 != '\0')
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return str1;
}
int main()
{
char ch[10] = "abc";
const char* str2 = "qwe";
my_strcpy(ch, str2);
printf("%s", ch);
return 0;
}
2) 字符串拼接操作
拼接两个字符串
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<assert.h>
#include<string>
char* my_strcat(char* str1, const char* str2)
{
assert(str1 != NULL && str2 != NULL);
int len = strlen(str1);
//给str1链接str2数据
int i = 0;
for (i; i < strlen(str2); i++)
{
str1[len + i] = str2[i];
}
str1[len+i] = '\0'; //字符串结尾标记'\0'
return str1;
}
int main()
{
char ch[10] = "abc";
char* res = my_strcat(ch, "def");
printf("%s",res);
return 0;
}
3) 字符串比较操作:strcmp
//方法一:数组
int my_strcmp(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 if(str1[i]>str2[i])
{
result = str1[i] > str2[i] ? 1 : -1;
break;
}
}
return result;
}
int main()
{
const char* str1 = "abcd";
const char* str2 = "abcd";
int res = my_strcmp(str1, str2);
printf("%d", res);
return 0;
}
方法二:指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 != NULL&&str2!=NULL);
bool flag;
int i = 0;
while (*(str1+i)!='\0'|| *(str2 + i) !='\0')
{
if (*(str1 + i) == *(str2 + i))
{
flag = 0;
}
else if (*(str1 + i) > *(str2 + i))
{
flag = 1;
break;
}
else
{
flag = -1;
break;
}
i++;
}
return flag;
}
int main()
{
const char* str1 = "abcd";
const char* str2 = "abcd";
int res = my_strcmp(str1, str2);
printf("%d", res);
return 0;
}
4).求字符串长度
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string>
int main()
{
char ch[] = {'h','e','l','l','o'};
char arr[] = "hello";
arr[0] = 's';
int len_ch = sizeof(ch) / sizeof(ch[0]); // 5
int len_arr = sizeof(arr) / sizeof(arr[0]);//6 多了一个 '/0'
int len_string = strlen(arr); //第一个'/0'前面字符个数
printf("ch: %d arr: %d 字符串长度:%d",len_ch,len_arr,len_string );
return 0;
}