目录
一、指针与变量
指针的含义
1.1 指针类型和指针变量
二、指针操作
三、指针与数组
3.1 用指针标识整型数组
3.2 指针运算
3.2.3指针数组
3.3.3 字符串指针
四、字符串内容
4.1 单字符的输入输出
4.2 函数
4.3.1 利用指针自己写一个求长度的函数
4.3.2 写一个strcmp函数
4.3.3 写一个strcpy函数
4.3.4 写一个strcat函数
一、指针与变量
指针的含义
每个变量有它的值,同时在计算机内存中占用一块存储区,该存储区的地址就是相应变量的地址,该存储区的保存的内容就是相应变量的值。
可以认为地址和指针是同义语,变量的指针就是变量的地址,保存变量指针的变量(地址)称为指针变量。
1.1 指针类型和指针变量
T *p;//T是指针的类型.
指针类所指向的类型可以是基本数据类型(int char float等等),也可以是构造型数据类型,指针类型,函数等;对于基本类型变量、数组成员、结构体变量、联合体变量等,用取地址符&获取变量的地址。
数组的地址与它的第一个元素(成员)的地址相同,用数组名字本身表示;函数的地址为函数的地址入口,用函数名字表示。
int x, y; int *iptr1, *iptr2; char *cptr; char ch = 'a'; //编译程序根据其变量声明的先后顺序为其在内存中分配空间; iptr1 = &x; iptr2 = &y;//&很重要; cptr = &ch; x = 8; y = 5; cout << "*iptr1=" << *iptr1 <输出结果:
指针所指变量和指针变量是两个不同的概念。指针变量即指针,它本身存储某个内存地址(某个变量的指针);指针所指变量是指针变量中所保存的内存地址对应的变量。
“ * ”用来访问指针所指变量的内容,称为间接引用运算符;* iptr 表示指针变量iptr所指变量的内容。
比如 int *p;//p输出地址 *p输出值
“ * ”的用法
① 放在表达式的指针变量之前,表示“对指针所指变量的访问”,称为间接引用操作符;
② 声明时表示指针类型 eg:* pi , * iptr;
二、指针操作
1、求地址“ & ”
“ & ”用来求“ 被操作对象 ”的地址(指针)。eg: &x 表示变量 x 在内存中的存储地址(即x的指针),若A的地址为ABD0,则&x 的值为ABD0。
2、取内容“ * ”
“ * ”与“ * ”互为逆运算。“ * ”运算访问地址表达式所指变量。eg : " x = * p " 是将指针p所指变量的值送入变量 x 中;“ * p = 5 ” 是将5送入指针 p 所指变量中。
3、赋值“ = ”
把一个指针赋值给某个指针变量。指针变量是指某变量指针(变量的地址)或函数的指针。
4、指向指针的指针
如果一个变量指针所指向的变量仍是一个指针变量,就构成指向指针变量的指针变量。
三、指针与数组
3.1 用指针标识整型数组
数组名是数组的首地址,也就是 a[0] 的首地址;指针值也是一个地址,如果一个指针p指向数组的首地址,则 p 与 a 表示的是同一个地址。数组名是指针,指针也是数组名。可以认为数组名是常量指针。
int a[5]; int *p; p = a;//也可以使用 p = &(a[0]);数组名不代表整个元素的地址,只代表数组的首地址。访问数组的第 i 个元素可以用数组名也可以用指针变量,在执行 p = a 以后以下方式等价
a[i]; *(a + i); p[i]; *(p + i);//等价 表示数组的第i个元素指针和数组的关系
//指针与数组的关系 #includeusing namespace std; int main() { int a[5]; int i; int* p; p = a;//注意!!!!! for (i = 0; i < 5; i++) { cin >> a[i]; } for (i = 0; i < 5; i++) { cout << "a[i] = " << a[i] << " "; } cout << endl; for (i = 0; i < 5; i++) { cout << "*(a + i) = " << *(a + i)<< " "; } cout << endl; for (i = 0; i < 5; i++) { cout << "*(p + i) = " << *(p + i) << " "; } cout << endl; for (i = 0; i < 5; i++) { cout << "p[i] = " << p[i] << " "; } cout << endl; for (p = a; p < a + 5; p++) {//!!!!!!!! cout << "*p = " << *p << " "; } cout << endl; system("pause"); return 0; } 运行结果
3.2 指针运算
3.2.1、加运算( ++ )
如果指针值指向数组的一个元素,C语言允许对相应指针值加上一个整数表达式。把指针 p 与一个整数k相加,得到的结果仍是一个指针值,该值指向的是“数组 a 从 p 原来所指的元素开始,向数组尾部移动k个元素后的元素”。
int * p; int a[100]; p = &(a[10]); p = p + 3; //此时的p所指向的是a[13];3.2.2、减运算( -- )
与加运算类似,向数组首部移动。如果两个指针类型相容,则他们可以进行相减运算。
注意:①两个指针不能加法运算 ②函数指针和 void * 类型不可以进行加减运算
③加减运算时注意边界
3.2.3、判等和关系运算
(1)、判等( == 或 !=)或者bool类型;
(2)、关系判断(> >= < <=);
#includeusing namespace std; int main() { int a[50] = { 0 }; int* ptr; int u = 0; int* q; ptr = &(a[4]); for (int i = 0; i < 50; i++) { a[i] = i * 10; } //① ptr++,q指向a[4],ptr指向a[5] q = ptr++; cout << "ptr++ = " << *(ptr++) << endl; //② *ptr++ 就是 *(ptr++) a[5] u = *(ptr++); cout << " *(ptr++) = " << *(ptr++) << endl; //③ (*ptr)++ *ptr所指向的变量值加一 即a[*ptr]+1 a[7]+1 u = (*ptr)++; cout << "(*ptr)++ = " << (*ptr)++ << endl; //④ ++ptr q = ++ptr; cout << " ++ptr = " << *(++ptr) << endl; //⑤ *(++ptr) u = *(++ptr); cout << "*(++ptr) = " << *(++ptr) << endl; system("pause"); return 0; } 多维数组 : 行优先, 基点+行数*每行元素个数+剩余行的零头个数;
3.2.3指针数组
//由指针构成的数组 #includeusing namespace std; int main() { int a[5] = { 1,2,3,4,5 }; int *n[5];//n数组内的元素都是指针 //指针的指针 int** p = n;//指向n数组的首元素地址 for (int i = 0; i < 5; i++) { n[i] = &(a[i]);//给n数组赋值 } for (int j = 0; j < 5; j++, p++) { cout << **p << " "; } cout << endl; system("pause"); return 0; } 3.3.3 字符串指针
字符串实质上是常量字符数组,可以使用字符数组保存字符串。
①字符串指针与字符数组是不同的。
②字符串指针名字与字符串数组名字是不同的。
③字符数组名字是一个指针常量,但是字符串指针名字是一个指针变量(因为它可以指向任何字符串)
注意:数组不能整体赋值
字符数组:作为本地变量自动回收,只读
指针:这个指针可以指向任何字符串
需要处理参数或者动态分配空间(malloc)时利用指针表达字符串
char * str; char st[20]="hello world";//正确 str="hello world";//是正确的,str是指针变量,指向常量字符串 char str1[20];//指针常量 str1[]="hello world";//错误的四、字符串内容
4.1 单字符的输入输出
char str[20]; //读入时在vs中用scanf读入会报错,可以修改为scanf("%s",str,40); //40并不是一个固定的值putchar和getchar的使用
#includeusing namespace std; int main(){ int ch; while((ch = getchar()) != EOF){ putchar(ch); } cout << "EOF" << endl;//Ctrl+c 强制终止程序运行 ,不可以输出EOF //Ctrl+D 程序结束运行 可以输出"EOF" system("pause"); return 0; } 4.2
函数 //主要使用的一些函数 #includeusing namespace std; #include int main() { char str0[30] = "hello world"; char str1[30] = "hello"; char str2[30] = "world"; //①求字符串长度的函数 int length = strlen(str0); cout << "length = " << length << endl; //②比较两个字符串字典序的函数 strcmp //若第二个参数字典序大于第一个参数则结果为 1 ,否则为 -1 ,相等则为0 int result = strcmp(str1, str2); cout << "result = " << result << endl; //③将 str2 赋值给 str1 strcpy(str1, str2); cout << "str1 = " << str1 << endl; system("pause"); return 0; } 运行结果
4.3.1 利用指针自己写一个求长度的函数
#includeusing namespace std; int mylen(char* str) { int count = 0; char* p = str; while (*p != ' ') {//字符串结束符' ' p++; count++; } return count; } int main() { char str[100] = { 0 }; cin.getline(str, sizeof(str)); cin >> str; int length = mylen(str); cout << length << endl; return 0; } 4.3.2 写一个strcmp函数
#includeusing namespace std; #include int mycmp(char* str0, char* str1) { int index = 0; // while(str0[index]==str1[index]&&str0[index]!=' '){ // index++; // } // *str0=*str1; while (*str0 == *str1 && *str0 != ' ') { str0++; str1++; } //return str0[index]-str1[index]; return *str0 - *str1; } int main() { char str1[20] = "abc"; char str2[20] = "abd"; int result = mycmp(str1, str2); cout << result << endl; system("pause"); return 0; } 4.3.3 写一个strcpy函数
#includeusing namespace std; #include int mycpy(char* str0, char* str1) { while (*str1 != ' ') { *str0 = *str1; str1++; str0++; } *str0 = ' '; //return str0[index]-str1[index]; //return *q; } int main() { char str1[30] = " "; char str2[30] = " "; gets(str2);//读入字符串 mycpy(str1, str2); //cout<<*str1< 4.3.4 写一个strcat函数
//将 str1 拼接到 str0 后面 #includeusing namespace std; #include int mycat(char* str0, char* str1) { int i = strlen(str0); char* p = str0 + i; while (*str1 != ' ') { *p = *str1; str1++; p++; } *p = ' '; } int main() { char str1[30] = " "; char str2[30] = " "; gets(str1); gets(str2); mycat(str1, str2); //cout<<*str1<



