目录
一、指针与变量
指针的含义
每个变量有它的值,同时在计算机内存中占用一块存储区,该存储区的地址就是相应变量的地址,该存储区的保存的内容就是相应变量的值。
可以认为地址和指针是同义语,变量的指针就是变量的地址,保存变量指针的变量(地址)称为指针变量。
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 <<endl;
cout << "*iptr2=" << *iptr2 <<endl;
cout << "*cptr=" << *cptr <<endl;
cout << "iptr1=" << iptr1 <<endl;
cout << "iptr2=" << iptr2 <<endl;
cout << "cptr=" << cptr <<endl;
输出结果:
指针所指变量和指针变量是两个不同的概念。指针变量即指针,它本身存储某个内存地址(某个变量的指针);指针所指变量是指针变量中所保存的内存地址对应的变量。
“ * ”用来访问指针所指变量的内容,称为间接引用运算符;* 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个元素
指针和数组的关系
//指针与数组的关系
#include<iostream>
using 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)、关系判断(> >= < <=);
#include<iostream>
using 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指针数组
//由指针构成的数组
#include<iostream>
using 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的使用
#include<iostream>
using 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 <string.h>函数
//主要使用的一些函数
#include<iostream>
using namespace std;
#include<string.h>
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 利用指针自己写一个求长度的函数
#include <iostream>
using namespace std;
int mylen(char* str) {
int count = 0;
char* p = str;
while (*p != '\0') {//字符串结束符'\0'
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函数
#include<iostream>
using namespace std;
#include<string.h>
int mycmp(char* str0, char* str1) {
int index = 0;
// while(str0[index]==str1[index]&&str0[index]!='\0'){
// index++;
// }
// *str0=*str1;
while (*str0 == *str1 && *str0 != '\0') {
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函数
#include<iostream>
using namespace std;
#include<string.h>
int mycpy(char* str0, char* str1) {
while (*str1 != '\0') {
*str0 = *str1;
str1++;
str0++;
}
*str0 = '\0';
//return str0[index]-str1[index];
//return *q;
}
int main() {
char str1[30] = " ";
char str2[30] = " ";
gets(str2);//读入字符串
mycpy(str1, str2);
//cout<<*str1<<endl;//只输出第一个字母
cout << str1 << endl;
system("pause");
return 0;
}
4.3.4 写一个strcat函数
//将 str1 拼接到 str0 后面
#include<iostream>
using namespace std;
#include<string.h>
int mycat(char* str0, char* str1) {
int i = strlen(str0);
char* p = str0 + i;
while (*str1 != '\0') {
*p = *str1;
str1++;
p++;
}
*p = '\0';
}
int main() {
char str1[30] = " ";
char str2[30] = " ";
gets(str1);
gets(str2);
mycat(str1, str2);
//cout<<*str1<<endl;
cout << str1 << endl;
system("pause");
return 0;
}