【 C 】字符串常量

当一个字符串常量出现在表达式中时,它的值是个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。但是,当数组名用于表达式中时,它们的值也是个指针常量。我们可以对它们进行下标引用、间接访问以及指针运算。

这些操作对于字符串常量是不是也有意义呢?

看看下面这个表达式是什么意思?

"xyz" + 1

看上去像是一个垃圾!它好像是试图在一个字符串上面执行某种类型的加法运算。

但是,当你记得字符串常量实际上是一个指针常量时,它的意义就变得清楚了。这个表达式计算“指针值 + 1”的值。它的结果是个指针,指向字符串的第二个字符:y。

那么这个表达式又是什么呢?

*"xyz"

理解了第一个,后面的都好说:对一个指针执行间接访问时,其结果就是该指针指向的值。字符串常量的类型是指向字符的指针,所以这个间接访问得到的结果是字符‘x’。

我们继续放出大招:

"xyz"[2]

很简单,对一个指针进行下标访问是合理的,就像数组名也是一个指针常量,对其下标访问就是对数组中的元素进行访问,这个同理,表达式的值为一个字符‘z’。

下面给出一个错误的例子:

*( "xyz" + 4 )

这个表达式的结果是什么呢?

事实上,这是一个错误,它的偏移量4超过了字符串的访问,就像你访问一个数组的元素,超出了索引范围一样,这样有可能会出大事!这个表达式的结果是一个不可预测的值。

什么时候会用到类似这些形式的表达式呢?

《C与指针》给出了一个神秘函数的例子:

#include <stdio.h>

void mystery( int n )
{
    n += 5;
    n /= 10;
    printf("%s\n", "**********" + 10 - n );
}

最后一个标准输出语句使用了字符串常量,下面我们测试下这个函数执行的情况:

#include <stdio.h>
#define M 6

void mystery( int n )
{
    n += 5;
    n /= 10;
    printf("%s\n", "**********" + 10 - n );
}

int main()
{
    mystery( M );
    return 0;
}

我们通过改变M的值,来运行这个程序:

大家可在这个网站上实验:https://www.tutorialspoint.com/compile_c_online.php

当输入M = 10 时候:

?

输入M = 100时:

?

各位自行总结规律!
各位大侠如果觉得这个例子垃圾,那我们就再看一个例子:

这个例子在递归函数中也见过,非常好玩!

【 C 】深入了解递归

贴出来代码:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
	unsigned int quotient;

	quotient = value / 10;
	if(quotient != 0)
		binary_to_ascii(quotient);

	putchar(value % 10 + ‘0‘);

}

这个例子,如果你不太了解递归函数,恐怕会感到无解!

但它确实能实现把一个整型值转换为字符打印的操作。

测试下呗:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
	unsigned int quotient;

	quotient = value / 10;
	if(quotient != 0)
		binary_to_ascii(quotient);

	putchar(value % 10 + ‘0‘);

}

int main()
{
    binary_to_ascii(16);

    return 0;
}

?

下面我们对这个例子进行修改,以十六进制的形式打印结果值:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
	unsigned int quotient;

	quotient = value / 16;
	if(quotient != 0)
		binary_to_ascii(quotient);

	putchar( "0123456789ABCDEF"[value % 16] );

}

int main()
{
    binary_to_ascii(26);

    return 0;
}

?

这就很完美了,成功的运用了字符串常量是一个指针常量的意义来设计程序!

当然,如果觉得字符串常量难以理解的话,可以有一个简单的替代方案,但是代码没有字符串常量简洁:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
	unsigned int quotient, remainder;

	quotient = value / 16;
	if(quotient != 0)
		binary_to_ascii(quotient);

	remainder = value % 16;
	if( remainder < 10 )
        putchar( remainder + ‘0‘ );
    else
        putchar( remainder - 10 + ‘A‘ );

}

int main()
{
    binary_to_ascii(26);

    return 0;
}

?

原文地址:https://www.cnblogs.com/reborn521615/p/9650670.html

时间: 2024-08-10 10:14:43

【 C 】字符串常量的相关文章

Java中的字符串常量池

最近做到一个题目: 问题:String str = new String("abc"),"abc"在内存中是怎么分配的?    答案是:堆,字符串常量区. 题目考查的为Java中的字符串常量池和JVM运行时数据区的相关概念."abc"为字面量对象,其存储在堆内存中.而字符串常量池则存储的是字符串对象的一个引用. Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid&qu

string字符串常量池在内存中的位置

这里仅仅是举个简单的样例说明字符串常量池在内存中的位置. 闲言少叙,直接上代码. Java代码   <span style="font-size: large;">import java.util.ArrayList; public class Test { public static void main(String[] args) { String str = "abc"; char[] array = {'a', 'b', 'c'}; String

java字符常量与字符串常量的区别

形式上:字符常量是单引号引起的一个字符例:‘a’字符串常量是双引号引起的若干个字符"helloworld"含义上:字符常量相当于一个整形值(ASC||值),可以参加表达式运算,直接拿变量使用字符串常量代表一个地址值(该字符在内存中存放的位置)占内存大小:字符常量只占一个字节字符串常量占若干个字节字符型常量使用char型变量来存储字符串用char型的数组来存储 类型字符类型为char,字符串类型为string两者都是常量,区别于使用方法的不同

Java中字符串常量池的陷阱

public class TestCase { static String ab = "ab"; static String getA() { return "a"; } static String getAB() { return "ab"; } public static void main(String[] args) { // 1 String _ab = new String("ab"); System.out.pr

C++常量(C++数值常量、字符串常量、符号常量)

http://see.xidian.edu.cn/cpp/biancheng/view/104.html 字符串常量 用双撇号括起来的部分就是字符串常量,如"abc","Hello!","a+b","Li ping"都是字符串常量.字符串常量"abc"在内存中占4个字节(而不是3个字节),见图2.5. 图 2.5 编译系统会在字符串最后自动加一个'\0'作为字符串结束标志.但'\0'并不是字符串的一部分,它

Python学习总结4:字符串常量与操作汇总

参考博客:http://www.cnblogs.com/Camilo/archive/2013/09/21/3332267.html http://www.cnblogs.com/SunWentao/archive/2008/06/19/1225690.html 1. 字符串常量 string.digits:包含0-9的字符串    string.letters:包含所有大小写字母的字符串     string.lowercase:所有小写字母    string.printable:包含所有可

字符串常量池、堆、栈

String a="a"+"b"+"c" 创建了几个对象 这个问题涉及到了字符串常量池和字符串拼接 String a="a"+"b"+"c" 通过编译器优化后,得到的效果是 String a="abc" Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid"; 另一种就是使用new这种标准的构造对象的方法,

指针和字符串和字符串常量、用gdb来获取非法内存中的信息

例程1 #include<stdio.h> int main(void) { char *s="hello"; printf("%s\n", s); s[0]="H" //因为s指针指向的字符串"hello"是字符串常量,所以不能通过指针进行更改,所以这里会产生段错误 printf("%s\n", s); return 0; } 例程2 #include<stdio.h> #incl

使用struts2的标签s:if获取url中的参数值,并与字符串常量进行比较

大家都知道,jsp中最好不要写java脚本,稍微复杂一点的逻辑都会让代码十分难看,对于维护来说简直是噩梦.但是我们又不可能完全不在jsp中写java脚本,像<%= request.getContextPath()>这种方式,很方便而且也不会让代码很难看.当jsp中需要有复杂的逻辑判断或者循环的时候,最好使用标签库来提高代码的可维护性,比如标准的JSTL库,还有很常用的struts2标签库. 比如有一个url http://127.0.0.1:8080/demo/test.jsp?id=1 ,我

static关键字以及字符串常量的理解

一.作用域.链接属性以及存储类型: 1.      作用域:常见作用域有代码块.文件.函数以及原型作用域(只适用于在函数原型中声明的参数名). 2.      链接属性: a)        链接可以将多个目标文件链接生成最后的目标文件.链接属性则是决定如何处理在不同文件中出现的标识符. b)        链接属性总共有三种:external(外部).internal(内部)以及none(无).默认情况下标识符一般是外部或者无属性,但是,通过static关键字,则可以改变标识符的属性,将外部属