c言語あれこれ
逐次追加していくタイプの記事
文字列のあれこれ
#include <stdio.h>
#include <string.h>
int main(void) {
char t[20] = "ABCDEFGHIJK";
t[3] = '\0';
printf("%s",t); // ABCのみを表示
strcpy(t1, t); // コピー
printf("%s\n", t1);
printf("%lu", strlen(t1)); // 長さ
return 0;
}
文字列の入力
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n, i;
char *ptr;
printf("Enter number of characters to store: ");
scanf("%d", &n);
ptr = (char*)malloc(n*sizeof(char));
for(i=0; i < n; i++)
{
printf("Enter ptr[%d]: ", i);
/* notice the space preceding %c is
necessary to read all whitespace in the input buffer
*/
scanf(" %c", ptr+i);
}
printf("\nPrinting elements of 1-D array: \n\n");
for(i = 0; i < n; i++)
{
printf("%c ", ptr[i]);
}
// signal to operating system program ran fine
return 0;
}
文字列のポインタ
#include <stdio.h>
#include <string.h>
int main () {
// https://dixq.net/forum/viewtopic.php?t=11845
const char* message = "abcdef"; // 文字列のポインタ
printf("%s\n", message); // agcdef
printf("%d\n", strlen(message)); // 6
int m=0;
while(message[m] != '\0'){
printf("%c\n", message[m]);
m++;
}
const char* message_pointer = message;
while(*message_pointer != '\0'){ // 文字
printf("%c\n", *message_pointer);
message_pointer++;
}
参考
Difference between char* and const char*?
文字列の初期化
以下のコードの違い
char arr[] = "Hello World"; // array version
char ptr* = "Hello World"; // pointer version
上は、Hello Worldの文字列12文字分のスペース12byteをメモリ上に確保。
下は、Hello Worldの文字列12文字分のスペース12byteとその文字列の先頭を指すポインタ4byteの合計16byteをメモリ上に確保
- https://overiq.com/c-programming-101/character-array-and-character-pointer-in-c/
- https://it-ojisan.tokyo/c-char-init/
ポインタのポインタ
#include <stdio.h>
int main () {
int num = 12;
int *p_num = #
int **pp_num = &p_num;
printf("num: %d, &num: %p\n", num, &num);
printf("p_num: %p, *p_num: %d, &p_num: %p\n", p_num, *p_num, &p_num);
printf("pp_num: %p, *pp_num: %p, **pp_num: %d\n", pp_num, *pp_num, **pp_num);
}
um: 12, &num: 0x7ffee3a8d564
p_num: 0x7ffee3a8d564, *p_num: 12, &p_num: 0x7ffee3a8d558
pp_num: 0x7ffee3a8d558, *pp_num: 0x7ffee3a8d564, **pp_num: 12
動的メモリ管理
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int size = 10;
struct Student{
char name[30];
};
struct Student** students;
int main(){
students = (struct Student **)malloc(size*sizeof(struct Student *));
for(int i=0; i<size; i++){
students[i] = (struct Student *)malloc(sizeof(struct Student));
char name1[30];
sprintf(name1, "john %d", i+1);
strcpy(students[i]->name, name1);
}
for(int i=0; i<size; i++){
printf("%s\n", students[i]->name);
}
for(int i=0; i<size; i++){
free(students[i]);
}
free(students);
return 0;
}
関数の引数でポインタのポインタ
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ポインタ変数のアドレスを受け取るのでダブルポインタ(ポインタのポインタ)
int memory_alloc( char ** pptr, char * contents ) {
*pptr = malloc( strlen( contents ) + 1 );
if( *pptr == NULL ) {
return -1;
}
memset( *pptr , '\0' , strlen( contents ) + 1 );
strcpy( *pptr , contents );
return 0;
}
main() {
char * ptr;
int ret;
ret = memory_alloc( &ptr, "テストデータ" ); // ptrのアドレスを渡す。参照渡し
if( ret == -1 ) {
printf( "メモリ確保エラー\n" );
return -1;
}
printf( "ptr=%s\n" , ptr );
free( ptr );/* メモリ開放 */
}
配列
#include <stdio.h>
void incvec(int *const vec, int len){
for(int i=0; i<len; ++i) vec[i]+=i;
}
void addscalar(int *const vec, int len, int val){
for(int i=0; i<len; ++i) vec[i] += val;
}
void setvec(int *const vec, int len, int val){
for(int i=0; i<len; ++i) vec[i]=val;
}
void printvec(const int *const vec, int len){
for(int i=0; i<len; ++i) printf("%2d ", vec[i]);
putchar('\n');
}
#define LEN 10
int main(){
int vector[LEN];
setvec(vector, LEN, 0);
printvec(vector, LEN);
incvec(vector, LEN);
printvec(vector, LEN);
addscalar(vector, LEN, 2);
printvec(vector, LEN);
}
ref. https://www.quora.com/How-can-I-change-the-values-of-an-array-with-a-void-function-in-c
2次元文字列配列
#include <stdio.h>
void function(int n, int m, char array[][5]) {
// printf("%p\n", array);
for(int i=0; i< n; i++){
printf("%s\n", *(array+i));
}
}
int main() {
char array[3][5] = {"asdf", "bfds", "1111"};
// printf("%p\n", array);
function(3,5,array);
}
asdf
bfds
1111
mallocと関数ポインタの例
2つベクトルのサイズ、値を入力させて、そのscalar productを計算する
#include <stdio.h>
#include <stdlib.h>
// Write a program to calculate the scalar product of two vectors.
int* create_array(int size){
int *arr=NULL;
arr=(int*)malloc(size*sizeof(int));
for(int i=0;i<size;i++){
scanf("%d", arr+i);
}
return arr;
}
int main() {
int size;
printf("Enter size: ");
scanf("%d", &size);
int *vector1=NULL;
int *vector2=NULL;
printf("Enter elements of the 1st vector: \n");
vector1 = create_array(size);
printf("Enter elements of the 2nd vector: \n");
vector2 = create_array(size);
int sum=0;
for(int i=0;i<size;i++){
sum=sum + vector1[i]*vector2[i];
}
printf("scalar product: %d\n", sum);
int newsize;
printf("Enter a new size:");
scanf("%d", &newsize);
vector1=realloc(vector1,newsize*sizeof(int));
vector2=realloc(vector2,newsize*sizeof(int));
printf("Enter elements of the 1st vector again: \n");
vector1 = create_array(newsize);
printf("Enter elements of the 2nd vector again: \n");
vector2 = create_array(newsize);
sum =0;
for(int i=0;i<newsize;i++){
sum=sum + vector1[i]*vector2[i];
}
printf("scalar product: %d\n", sum);
return 0;
}
charとstringの違い
character is just a single character enclosed in single quotes. For example:
char initial = 'A'; /* initial declared to be a character */
And a character string is a sequence of 0 or more characters enclosed in double quotes. Each string is terminated by a NULL byte. Therefore, string containing 0 characters is called an empty string.
https://www.sanfoundry.com/c-tutorials-difference-between-character-string/
Linusがしていたポインターの話
What is the difference between char array and char pointer in C?
-
https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s
-
https://www.geeksforgeeks.org/whats-difference-between-char-s-and-char-s-in-c/
日本語の記事
char a[] = "abc";
char *b = "abc";
printf("%s %s\n", a, b); // abc abc
この二つには大きな違いがあります。
char amsg[]: char型の変数を4個実際に確保。その中に'a', 'b', 'c', '\0'を入れる。これらは普通の配列なので、自由にアクセス・変更できる。
char *pmsg: char型ポインタを1個だけ確保。プログラムのどこかで文字列リテラル"abcd"が確保される。そのリテラルのアドレスが入る。リテラルなので、アクセスは出来るが変更は出来ない。
why strchr() having "int" as second parameter.
参考
- https://eeic-software1.github.io/2020/ <- わかりやすい。
Discussion