一,c/c++字符串
1.C/C++中每個字符串都以字符’\0‘作為結尾,這樣我們就能很方便地找到字符串的最后尾部。
由於這個原因每個字符串都有一個額外的開銷,注意字符串越界的問題;
2.C/C++內存模型把字符串常量放到單獨的一個內存區域;
當幾個指針指向相同的字符串常量的時候,他們實際上會指向常量區那個的內存地址;
但是用字符串常量初始化數組,情況卻不一樣,這點很重要,考察你C能力的籌碼;
test.c:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <stdio.h>
int main() { char str1[] = "hello world"; char str2[] = "hello world"; char *str3 = "hello boy"; char *str4 = "hello boy"; if(str1 == str2) { printf( "str1 and str2 are same.\n"); } else { printf( "str1 and str2 are not same\n"); } if (str3 == str4) { printf( "str3 and str4 are same.\n"); } else { printf( "str3 and str4 are not same.\n"); } return 0; } |
運行結果:
str1 and str2 are not same
str3 and str4 are same.
Makefile:
1
2 3 4 5 6 7 8 9 10 11 12 |
.PHONY:clean
CC=gcc CFLAGS=-Wall -g BIN=test OBJS=test.o LIBS= $(BIN):$(OBJS) $(CC) $(CFLAGS) $^ -o $@ $(LIBS) %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN) |
str1和str2是兩個字符串數組,我們會為他們分配兩個長度為12個字節的空間(在棧區),
並且把常量區的“hello world”的內容分別拷貝的數組當中。
這是兩個初始地址不同的數組;
str3和str4是兩個指針,我們無須為她們分配內存來存儲字符串的內容,而只需要把他們指向“hello boy”在常量區中的地址就可以了,“hello world”這個字符串常量在內存中只有一個拷貝,因此str3與str4的值是一樣的。
二,替換空格
給定字符串中的空格替換成 ’%20‘
思路就是計算出替換后的字符串的長度,利用兩個指針,一個指向就字符串的末尾,一個指向新字符串的末尾;
進而從后往前面遍歷,這樣子節約時間,移位的效率高,因為沒有做多余的移位操作;
space.cpp:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
#include <iostream>
#include <cstring> #include <cstdio> using namespace std; /*length 為字符數組string的總的容量*/ void ReplaceBlank( char string[], int length) { if(string == NULL && length <= 0) { return; } /*originalLength為字符串string的實際長度*/ int originalLength = 0; int numberOfBlank = 0; int i = 0; while(string[i] != '\0') { ++ originalLength; if(string[i] == ' ') { ++ numberOfBlank; } ++ i; } /*newLength為把空格替換成‘%20’后的長度*/ int newLength = originalLength + numberOfBlank * 2; if (newLength > length) { return ; } int indexOforiginal = originalLength; int indexOfNew = newLength; while(indexOforiginal >= 0 && indexOfNew > indexOforiginal) { if(string[indexOforiginal] == ' ') { string[indexOfNew --] = '0'; string[indexOfNew --] = '2'; string[indexOfNew --] = '%'; } else { string[indexOfNew --] = string[indexOforiginal]; } -- indexOforiginal; } } void Test( char *testName, char string[], int length, char expected[]) { if(testName != NULL) printf( "%s begins: ", testName); ReplaceBlank(string, length); if(expected == NULL && string == NULL) { cout << "passed." << endl; } else if(expected == NULL && string != NULL) { cout << "failed." << endl; } else if(strcmp(string, expected) == 0) { cout << "passed." << endl; } else { cout << "failed." << endl; } } int main() { const int length = 100; char string[length] = "hello world"; char expected[] = "hello%20world"; ReplaceBlank(string, length); if(strcmp(string, expected) == 0) { cout << "passed." << endl; } else { cout << "failed." << endl; } return 0; } |
運行結果:
passed.
Makefile:
1
2 3 4 5 6 7 8 9 10 11 12 |
.PHONY:clean
CPP=g++ CFLAGS=-Wall -g BIN=test OBJS=space.o LIBS= $(BIN):$(OBJS) $(CPP) $(CFLAGS) $^ -o $@ $(LIBS) %.o:%.cpp $(CPP) $(CFLAGS) -c $< -o $@ clean: rm -f *.o $(BIN)Test1 begins: passed. |