Shammer's Philosophy

My private adversaria

substring 関数 - 20100930

substring 関数 - 20100926 - Shammerismで気になっていた、end が実際の文字列より大きい場合の対処を追加したバージョン。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * substring(const char str[], int s, int e){
    int start = s;
    int end = e;
    int length = end - start;
    if( length < 0 ){
	int temp = start;
	start = end;
	end = temp;
	length = length * -1;
    }
    if( end > strlen(str) ){
	end = strlen(str);
	length = end - start;
    }
    char * value = (char *)malloc(sizeof(char) * (length + 1));
    int i = 0;
    while( i < length ){
	value[i] = str[start + i];
	i++;
    }
    value[length] = '\0';
    return value;
}

int main(int argc, char * args[]){
    char * v1 = substring(args[1], 0, 3);
    char * v2 = substring(args[1], 100, 1);
    printf("substring(args[1], 0, 3) is v1, v1 value is %s, strlen(v1) is %zd, sizeof(v1) is %lu.\n", v1, strlen(v1), sizeof(v1));
    printf("substring(args[1], 100, 1) is v2, v2 value is %s, strlen(v2) is %zd, sizeof(v2) is %lu.\n", v2, strlen(v2), sizeof(v2));
    free(v1);
    free(v2);
    return 0;
}

実行結果は以下のような感じ。

$ ./a.out ABCDEFGHIJKLMNOPQRSTUVWXYZ
substring(args[1], 0, 3) is v1, v1 value is ABC, strlen(v1) is 3, sizeof(v1) is 8.
substring(args[1], 100, 1) is v2, v2 value is BCDEFGHIJKLMNOPQRSTUVWXYZ, strlen(v2) is 25, sizeof(v2) is 8.

strlen は文字列長に応じて変更されるけれども、sizeof の値は変更されない。これはポインタのためだろうか。文字列の扱いに慣れるのは非常に骨が折れそうだ。ポインタとして宣言されているが、文字列の長さは固定じゃないし、ポインタは実際には配列の先頭アドレスのはず。そうすると、実際に必要なメモリのサイズも文字長が長くなれば増えそうだが、実際にはそうならなかった。この辺の詳細について、理解できるときはくるのだろうか。。。