C语⾔指针的使⽤、字符串和指针详解(详细、易懂)
C语⾔指针笔记
刚开始了解指针是从交换两个变量开始,但是总是断断续续地学,每次都在看交换两个变量的函数,上周在课上正式学了指针,看的时候感觉懂了,但是⼀上机就不知道指针怎么⽤、参数怎么传。于是想整理⼀下指针的学习笔记,再去做实验。
⽂中有错别字或其他错误的话记得给我留⾔哦~
什么是指针?怎么定义?
指针是⼀个变量,其值为另⼀个变量的地址,内存位置的直接地址。就像其他变量或常量⼀样,您必须在使⽤指针存储其他变量地址之前,对其进⾏声明。定义指针的⼀般类型为:
<;类型> *<;变量标识符>,*<;变量标识符>,...;
指针变量声明的例⼦:
int*px;
float*q;
其中,定义变量px是⼀个指针,且是指向整型变量的指针变量;q是指向单精度型变量的指针变量。
怎么使⽤指针变量?
指针变量跟其他变量⼀样,若要引⽤,则先要初始化或赋值。与指针有关的运算符有两个:
1. &—取地址运算符
2. *指针运算符
刚学指针的时候对这两个运算符很蒙,不知道该⽤哪个,怎么⽤。刚开始学不⽤搞那么复杂,举个简单的例⼦:
int a=10;
c语言char的用法int*p;
p=&a;
printf("%d %d %p %p",a,*p,&a,p);
结果是:
10 10 000000CB5D3FF654 000000CB5D3FF654
因为变量的地址是系统随机分配的,故每次运⾏地址都不⼀样,但是输出&a和p是⼀个效果。a是⼀个普通变量,应该在前⾯加个"&“才能取到a的地址,⽽p是⼀个指针变量,它存的就是a的地址,故前⾯不⽤取地址符”&"。
对于取值还是取地址,为了⽅便记忆与理解,我是这样记的:
仅仅⼀个p的话,它的值就是a的地址,*p的话就是取到a的值10。
指针和数组的关系是什么?
假设程序中有以下语句:
int a[20],*p;
p=&a[2];
假设程序中有以下语句:
int a[20],*p;
p=&a[2];
这⾥先把a[2]看成⼀个普通变量⽽不是数组,由上⾯的讲解假设程序中有以下语句:
int a[20],*p;
p=&a[2];
这⾥先把a[2]看成⼀个普通变量⽽不是数组就好理解了。
C语⾔规定数组名代表数组⾸地址,即数组第⼀个元素的地址,⼀下两个语句是等价的:
int a[20],*p;
p=a;
p=&a[0];
注意:在程序运⾏过程中,⼀个数组所占⽤的存储区是不变的,因此数组名是⼀个常量,故只能引⽤数组名,⽽不能对其进⾏赋值。
如a=&x;是⾮法的。通过数组名取地址前⾯不⽤"&",因为数组名本⾝就是⼀个地址,⽽通过元素取地址的话前⾯就要加"&"。
a是常量,a++是⾮法的,但p是指针变量,p++是合法的。
int*p1,*p2;
int a[20],k=5;
p1=&a[k];
p2=&a[1];
p1+i ——表⽰&a[k+i],即a[k+i]的地址
p1-i ——表⽰&a[k-i],即a[k-i]的地址
p1-p2 ——表⽰k-1,即a[k]与a[1]之间相隔的元素个数
如何通过指针存取数组元素?
已知数组名就是数组中第⼀个元素的地址,以下两个语句是等价的:
*a=65;
a[0]=65;
那么如何通过指针存取数组中其他元素呢?
C语⾔约定如果⼀个指针p指向a[i],则p+1指向a[i+1],因此以下两个语句是等价的:
*(a+1)=80;
a[1]=80;
注意:"*“的优先级⽐”+“⾼,”*(a+1)"中的括号是不可省略的,*a+1表⽰先取第⼀个元素的值,再加1。
字符串和指针
我们先来看⼀段代码:
#include<stdio.h>
int main()
{
char*s1="abcde";
char s2[]={"abcde"};
printf("%s,%c%s,%c\n",s1,*s1,s1+1,s1[1]);
printf("%s,%c,%s,%c\n",s2,*s2,s2+1,s2[1]);
return0;
}
运⾏结果为:
abcde,a,bcde,b
abcde,a,bcde,b
注意输出⼀个字符和输出字符串的区别。
当⽤指针时,如s1,s1+1,s2等表⽰⼀个字符串,该字符串从指针所指字符开始直⾄字符串结束标志’\0’;⽽当⽤*s1,s1[1],*(s1+1),s2[0]等时,表⽰的是⼀个字符,即指针所指的字符或位于该下标的字符元素。由此可见,字符数组和字符指针在使⽤上是相似的。但是两者⼜是有区别的:
字符指针
字符串指针变量本⾝是⼀个变量,⽤于存放字符串的⾸地址。⽽字符串本⾝是存放在以该⾸地址为⾸的⼀块连续的内存空间中并以 \0 作为串的结束。
char *ps="C Language";
顺序是:
1.分配内存给字符指针;
2.分配内存给字符串;
3.将字符串⾸地址赋值给字符指针;
char*ps;// ps 字符串指针,是指针,是⼀个变量
ps="C Language";/* ps 为字符串的⾸地址,利⽤ ps++ 可遍历字符串,字符串存储
在以 ps 为开始地址的地段连续的内存空间中,并以 \0 作为字符串的结束。*/
这⾥有两点需要考虑清楚的地⽅:
1.*a只是指向⼀个字符
#include<stdio.h>
#include<stdlib.h>
int main(void){
char*a="bcd";
printf("输出字符:%c \n",*a);/*输出字符,使⽤"%c"*/
printf("输出字符:%c \n",*(a+1));/*输出字符,使⽤"%c"*/
printf("输出字符串:%s \n", a);/*输出字符串,使⽤"%s";⽽且a之前不能有星号"*" */
system("pause");/*为了能看到输出结果*/
}
运⾏结果:
b c bcd
2.若字符串常量出现在表达式中,代表的值为该字符串常量的第⼀个字符的地址。所以"hello"仅仅代表的是其地址。原声明⽅式相当于⼀下声明⽅式:
char*a;
a="hello";/"hello"仅代表第⼀个字符的地址
字符数组
字符数组是由若⼲个数组元素组成的,它可⽤来存放整个字符串(即⽤字符数组来存放字符串)。在C语⾔中,将字符串作为字符数组来处理(c++中不是)。
(1)可以⽤字符串常量来初始化字符数组:
char str[]={"hello"};
也可以省略花括号:
char str[]="hello";/系统⾃动加⼊\0
注意:上述这种字符数组的整体赋值只能出现在字符数组初始化时使⽤,不能⽤于字符数组的赋值,字符数组的赋值只能对其元素⼀⼀赋值。
下⾯的赋值⽅法是错误的:
char str[20];
str="hello";
在C语⾔中,可以⽤两种⽅法表⽰和存放字符串:
char a[]="hello";/⽤字符数组存放⼀个字符串
char*a="hello";/⽤字符指针指向⼀个字符串
两种表⽰⽅式的字符串输出都⽤:printf("%s",a);
%s表⽰输出⼀个字符串,给出字符指针变量a(对于第⼀种表⽰⽅法,字符数组名即是字符数组的⾸地址,与第⼆种中的指针意义是⼀致的),则系统先输出它所指向的⼀个字符,然后使a⾃动加1,使之指向下⼀个字符,纸到遇到字符串结束标志符\0。
字符串指针
string* str可以赋值:
string* str ={"hello","world"};
// 对⽐与 char *name = "wang" = {'w','a','n','g'}
// *(str) = "hello", *(str+1) = "world"
// *(*(str)+1) = 'e'
也就是说每个元素都是string类型的,跟char是不⼀样的,不过string可以⽤char**来代替:
string=char*;
string*=char**;
(字符串)指针数组
实例:
#include<stdio.h>
void main()
{
char*str[]={"Hello","C++","World"};//char (*str)[] = ...
int i;
for(i=0; i<3; i++)
printf("%s\n", str[i]);
}
// str[0]字符串"hello"的⾸地址,str[0]+1:字符串"hello"第⼆个字符'e'的地址,str[2]=str+2:第三个字符串"world"的⾸地址
// str[1]字符串"C++"的⾸地址
// str[2]字符串"world"的⾸地址
或者:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char*str[3]={"Hello","C++","World"};
printf("%s,%s,%c",str[0],str[0]+1,*(*(str+2)+1));
}
结果:
Hello ello o
char *a[]:表⽰哦a是数组,数组中的元素是指针,指向char类型,(数组⾥⾯所有的元素是连续的内存存放的),数组名是数组第⼀个字节的内存地址,并且数组名a也表⽰指针。所以a并不表⽰a地址存储的内容,⽽是a地址本⾝。
a+1:表⽰a的第⼆个元素的内存地址,所以是加8字节。(因为a的元素是char指针,所需要的空间为8字节(64位))
*(a+1):表⽰a这个数组的第⼆个元素的内容(是个char类型的指针,本例表⽰world字符串的地址)
*(*(a+1)):表⽰a这个数组的第⼆个元素的内容(char指针)所指向的内容(w字符)
char * a[10]:表⽰限定这个数组最多可存放10个元素(char指针),也就是说这个数组占⽤10*8=80个字节
a+1=>*(a+1)=>*(a+1)[0]指针(地址)指针内容(字符串)字符
char*argv:理解为字符串
char**argv:理解为字符串指针
char*argv[]:字符串指针数组
C语⾔有两种表⽰字符串的⽅法,⼀种是字符数组,另⼀种是字符串常量,它们在内存中的存储位置不同,使得字符数组可以读取和修改,⽽字符串常量只能读取不能修改。
参考:[1] [2]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论