C语言 指针的内容

目录

一、指针与变量

指针的含义

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 <<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;
}

  • 23
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值