字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以 \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[]={"Iamhappy"};
可以省略花括号
char str[]="Iamhappy"; # 系统自动加入 \0
注意:上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值。
下面的赋值方法是错误的:
char str[20];
str="Iamhappy";
对字符数组的各元素逐个赋值。
char str[10]={'I','','a','m','','h','a','p','p','y'};
在 C 语言中,可以用两种方法表示和存放字符串:
(1)用字符数组存放一个字符串
char str[]="IloveChina";
(2)用字符指针指向一个字符串
char *str="IloveChina";
两种表示方式的字符串输出都用:printf("%s\n", str);
%s 表示输出一个字符串,给出字符指针变量名 str(对于第一种表示方法,字符数组名即是字符数组的首地址,与第二种中的指针意义是一致的),则系统先输出它所指向的一个字符数据,然后自动使 str 自动加 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 <string.h>
int main()
{
char *str[] = {"Hello", "C++", "World"};
char **p;
for(p=str; p<str+3; p++)
puts(*p); #*p为字符串首地址,*p[0]为字符串的第一个字符地址
}
实例
#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));
system("pause");
}
结果为:
Hello,ello,o
格式:char* na[N] = {"li", "zh", "li", "zh", "li"};
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字节。
#w: a+1 => *(a+1) => *(a+1)[0]
指针(地址) 指针内容(字符串) 字符
四
char *argv:理解为字符串
char **argv:理解为字符串指针
char *argv[]:字符串指针数组
int main(int argc, char*argv[])
这是一个典型的数组名(或者说是指针数组)做函数参数的例子,而且还是没有指定大小的形参数组。
有时为了再被调用函数中处理数组元素的需要,可以另设一个形参,传递需要处理的数组元素的个数。而且用数组名做函数实参时,不是吧数组元素的值传递给形参,而是把实参数组的首元素的地址传递给形参数组,这样两个数组久共同占有同一内存单元。 和变量作函数参数的作用不一样。
可以去看看关于数组作为函数参数和指针数组作main函数形参方面的例子。谭浩强的那本书讲的很细,对这个有详细的解释。
1. 当 char [] 作为函数的参数时, 表示 char *. 当作为函数的参数传入时, 实际上是拷贝了数组的第一个元素的地址。
所以 void test (char a[]) 等同于 void test ( char * a )
char x[10] ;
然后调用 test(x) 则等同于把 x 的第一个元素的地址赋予给参数 a。
2. char * a 和 char a[]
-
相同点 : a都是指针, 指向char类型。
-
不同点 : char a[] 把内容存在stack。char *a 则把指针存在 stack,把内容存在 constants。
3. char * a[10] 和 char a[10][20]
-
相同点 : a 都是2级指针, *a 表示一级指针, **a 表示内存中存储的内容。
-
不同点 : char * a[10], 数组由char * 类型的指针组成; char a [10][20] 表示一位放10个元素, 二维放20个元素, 值存放地是一块连续的内存区域, 没有指针。
4. 小窍门 : [] 和 * 的数量对应, 如 char a[][] 的指针层数是 2, 相当于 char **a; char *a[] 也是如此, 两层指针. 迷糊的时候数数到底有几个 * 几个 [], 就知道什么情况下存储的是内容还是地址了 ? 如 char a[][] 的情况里面: &a, a, *a 都是地址, **a 是内容。
原文地址:https://www.cnblogs.com/cj2014/p/3726380.html
有关C++ 字符、字符串、字符数组、字符串指针、指针数组的更多相关文章
- ruby - 如何从 ruby 中的字符串运行任意对象方法? - 2
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
- Ruby 解析字符串 - 2
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
- ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
- ruby-on-rails - unicode 字符串的长度 - 2
在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)
- ruby - 将差异补丁应用于字符串/文件 - 2
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
- ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
- ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
- ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
- ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby 中生成它们? - 2
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
- ruby - 多次弹出/移动 ruby 数组 - 2
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
随机推荐