1. 程式人生 > >C++字串字面值常量解析(string literal)

C++字串字面值常量解析(string literal)

首先本文的物件是這麼一段程式碼:

char * getResult0()
{
	char *s = "This is a string";
	return s;
}

char * getResult1()
{
	char s[] = "This is a string";
	return s;
}

兩段程式碼非常相似,但是函式getRsult0返回的是字面值字元陣列,函式getResult1返回的是靜態陣列。靜態陣列在棧上面分配的,因此函式返回的時候,已經不存在了,返回的指標懸空,因此編譯報錯!但是getResult0編譯執行完全沒有問題,這與字串字面值的特殊性有著重要的關係!

字串字面常量不同於普通的區域性變數,具有static duration lifetime,這整個程式的生命週期中都將存在

原文出自 : C99 standard 6.4.5/5 "String Literals - Semantics":

The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence

為驗證上面的結論,看一下程式碼:

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;

char * getResult()
{
	//返回靜態字元陣列
	char *s= "This is a string";
	return s;
}

char * otherResult()
{
	//返回動態分配字元陣列
	char *s = new char[17];
	strcpy(s,"This is a string");
	return s;
}
int main()
{
	char *s = getResult();
	cout << "Adress is : " << (int)s <<" Value is :"<<s <<endl;
	char *t = otherResult();
	cout << "Adress is : " << (int)t <<" Value is :"<<t <<endl;
	char *k = "This is a string";
	cout << "Adress is : " << (int)k <<" Value is :"<<k <<endl;
	//區域性變數
	int a = 0;
	cout << "Adress is : " << (long)&a <<" Value is :"<<a <<endl;
	//區域性指標變數
	int *b = new int(0);
	cout << "Adress is : " << b <<" Value is :"<<*b <<endl;
	//
	system("pause");
	return 0;
}

其執行結果如下:
Adress is : 1734656 Value is :This is a string
Adress is : 2249944 Value is :This is a string
Adress is : 1734656 Value is :This is a string
Adress is : 4520584 Value is :0
Adress is : 00225528 Value is :0
請按任意鍵繼續. . .
不同機器上執行的地址是不同的!每次執行相同的程式結果也會有差異。

s和k的地址是相同的,因為內容完全相同,這就說明返回字串字面常量的時候,該字面常量是在一段特殊的區域叫只讀儲存區分配的,不同於普通的靜態陣列和內建型別,這些在棧上面分配,並且有編譯器去管理釋放。

C++返回指標,不能返回指向區域性物件的指標!!!但是字串字面常量不是區域性物件,而是在整個程式生命週期中都存在的靜態常量。因此可以返回指向該地址的引用!明顯可以看出,a,b,k,t記憶體區域都相差很大,因為他們作用域不同。通過這些結果能夠大致瞭解C++字面字串常量!

t是動態分配的,不是常量,是堆上分配的空間。堆上面分配的空間和普通型別的區域性變數的生命週期是不一樣的,須有程式設計師主動的釋放。

給一條stackoverflow上面的問答連結,感興趣的可以看看:

相關推薦

C++字串面值常量解析string literal

首先本文的物件是這麼一段程式碼: char * getResult0() { char *s = "This is a string"; return s; }char * getResult1() { char s[] = "This is a string";

C++ 字串面值常量的問題

1:形式如: char* str=字面值常量 如下面程式碼:   char*  pc= "10000";   *(pc + 1) = '1';   cout << pc << endl;   cout << *pc << en

C++中面值常量面值型別

作者:zhaojia92  來源:CSDN  原文:https://blog.csdn.net/zhaojia92/article/details/50831436  版權宣告:本文為博主原創文章,轉載請附上博文連結!      

CC++中字串String字串字面量String Literal的區別

轉自:http://www.360doc.com/content/12/0511/19/7775902_210379219.shtml C/C++中的物件指的是一塊儲存區。字串字面量是不需要建立過程就可以使用的物件,所以它既沒有變數那樣的宣告或者定義(字串字面量是無名物件

Pandas學習筆記,符串方法string method

api long top method hand capi borde tle row 一般語法格式Series.str.method()。具體方法見http://pandas.pydata.org/pandas-docs/stable/api.html#string-ha

字串程式設計題題目解析From leetcode——1

1. Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0’s and 1’s, and all the

網絡編程中的常見陷阱之 0x十六進制數C++面值常量

十六進制 aid word 網絡編程 情況 技術分享 fill 截斷 常見 十六進制數相等的推斷 請問例如以下程序的輸出是神馬? #include <iostream> #include <string> using namespace std

c字串string物件、字串面值的區別

一、字串字面值 字串字面值是一串常量字元,字串字面值常量用雙引號括起來的零個或多個字元表示,為相容C語言,C++中所有的字串字面值都由編譯器自動在末尾新增一個空字元。 字串沒有變數名字,自身表示自身 "Hello World!" //simple string l

字串面值C風格字串C++風格字串

一、字串字面值 字串字面值是一串常量字元,字串字面值常量用雙引號括起來的零個或多個字元表示,為相容C語言,C++中所有的字串字面值都由編譯器自動在末尾新增一個空字元。 字串沒有變數名字,自身表示自身 "Hello World!" //simple string literal "" //em

C#中的字串string

1.字串搜尋: string s="ABC科學"; int i=s.IndexOf("科"); 注意:1)索引從0開始,如果沒有找到則返回值為-1;            2)C#中,ASCII和

C/C++中的面值常量常量以及變數

1.字面值常量 在C/C++中,4、3.1415926、0x24、"BEIJING"等等,都稱為字面值常量。稱之為字面值是因為只能用它的值來稱呼它,稱為為常量是因為它的值不能被修改。舉例說明: 20、

idea 14or maven 未結束字串面值 非法的表示式開始

[ERROR] *.java:[38,27] 未結束的字串字面值 [ERROR] *.java:[38,53] 需要 ';' [ERROR] *.java:[41,19] 需要 ')' [ERROR] *.java:[41,12] 不是語句 [ERROR]

C++11 理解 (十八) 之 字串面值

標準C++提供了兩種字串字面值。第一種,包含有雙引號,產生以空字元結尾的const char陣列。第二種有著前標L,產生以空字元結尾的const wchar_t陣列,其中wchar_t代表寬字元。對於Unicode編碼的支援尚付闕如。 為了加強C++編譯器對Unicod

Java字串String Pool深度解析

在工作中,String類是我們使用頻率非常高的一種物件型別。JVM為了提升效能和減少記憶體開銷,避免字串的重複建立,其維護了一塊特殊的記憶體空間,這就是我們今天要討論的核心,即字串池(String Pool)。字串池由String類私有的維護。       我們知道,在

Python 符串操作string替換、刪除、截取、復制、連接、比較、查找、包含、大小寫轉換、分割等

brk 分割 掃描 char 去空格 之前 特殊符號 strip () 去空格及特殊符號 s.strip().lstrip().rstrip(‘,‘) 復制字符串 #strcpy(sStr1,sStr2) sStr1 = ‘strcpy‘ sStr2 = sStr1

C++中路徑的處理方法string

ble fin ase names 復制字符串 ostream 是否 substr() 新的 string 類提供字符串處理函數,利用這些函數,程序員可以在字符串內查找字符,提取連續字符序列(稱為子串),以及在字符串中刪除和添加。我們將介紹一些主要函數。 1.函數find_

Java_51_組合_內部類詳解_字串String_equals和==的區別

組合 使用組合,可以獲得更多的靈活性,你甚至可以在執行的時候才決定哪幾個類組合在一起。 使用繼承,他是一種高度耦合,派生類和基類被緊緊的綁在一起,靈活性大大降低,而且,濫用繼承,也會使繼承樹變得又大又複雜,很難理解和維護。 如果是is-a關係,用繼承。【是一個[物件]】 如果是h

Python之字串切片String Slice

1、切片操作可以從一個字串中,擷取一個字串,Python牛掰之處,好方便 2、看下基本的語法,這是一個全包括的狀態 [start:end:step] 3、預設的幾種用法 先提及幾個關鍵概念: a、第一個字元的下標是0,即從左到右,是從0開始,然後1、2、3、4、5 b、最後一個

【LeetCode】443. 壓縮字串String Compression

【 英文練習 | 中文練習 】 題目描述: 給定一組字元,使用原地演算法將其壓縮。壓縮後的長度必須始終小於或等於原陣列長度,陣列的每個元素應該是長度為 1 的字元(不是 int 整數型別),在完成原地修改輸入陣列後,返回陣列的新長度。 示例 1: 輸入: ["a","a","

String原始碼解析JDK1.8

1、string類的定義 public final class String implements java.io.Serializable, Comparable<String>, CharSequence {} java.io.Serializa